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 22-01-2015
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Peticion de revision de metodos

Hola amigos, ya tengo implementado los metodos de mi clase para depuración y me va genial pero me gustaria que vieran esas funciones a ver que opinan:

En el "public" del TDebugger.cpp puse estos métodos:
Código PHP:
bool __fastcall InsertDLL(char *DllNameint NameDllLength);
bool __fastcall DeleteDLL(void *hLibModule); 
Y en el "private":
Código PHP:
TList *ListapMemoriaAuxDllsInyectadas, *ListapMemoriaAuxDllsALiberar, *ListaBPsLoadDll, *ListaBPsUnloadDll, *ListaBackupEIPOnLoadDll, *ListaBackupEIPOnUnloadDll;
unsigned long *pLoadDLL, *pUnloadDLL, *BPLoadDll, *BPUnloadDll, *BackupEIPOnLoadDll, *BackupEIPOnUnloadDll
Funcion que inserta el codigo para cargar la dll:
Código PHP:
bool __fastcall TDebugger::InsertDLL(char *DllNameint NameDllLength)
{
   
BYTE LoadDLL[] = {0x600x680x000x000x000x000xE80x000x000x000x000x610x90};
   
bool ret false;
   
LPTHREAD_START_ROUTINE hLib;
   
unsigned long pNameDllpDirCall;

   
//Obtengo memoria para los punteros que irán a las listas
   
pLoadDLL = new (std::nothrow)unsigned long;
   
BPLoadDll = new (std::nothrow)unsigned long;
   
BackupEIPOnLoadDll = new (std::nothrow)unsigned long;

   if(
pLoadDLL == NULL || BPLoadDll == NULL || BackupEIPOnLoadDll == NULL)
   { 
//Si hubo algun problema
      
if(pLoadDLL != NULL){ //Si se obtuvo memoria para esta, la libero
         
delete pLoadDLL;
      }
      if(
BPLoadDll == NULL){ //Si se obtuvo memoria para esta, la libero
         
delete BPLoadDll;
      }
      if(
BackupEIPOnLoadDll == NULL){ //Si se obtuvo memoria para esta, la libero
         
delete BackupEIPOnLoadDll;
      }
   }else{ 
//Si no hubo error
      
try{
         
ListapMemoriaAuxDllsInyectadas->Add(pLoadDLL); //Añado la nueva direccion allocada a la lista de inyecciones
         
ListaBPsLoadDll->Add(BPLoadDll); //Añado el nuevo BP de salida a la lista de BPs de salida
         
ListaBackupEIPOnLoadDll->Add(BackupEIPOnLoadDll); //Añado la nueva direccion al nuevo EIP de retorno

         // Localizo memoria en el espacio de direcciones de la víctima
         
*pLoadDLL = (unsigned long)VirtualAllocEx((HANDLE)GetHProcess(), NULL, (sizeof(LoadDLL) + NameDllLength 1), MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);

         if(*
pLoadDLL){ //Si se obtuvo memoria
            
pNameDll = *pLoadDLL sizeof(LoadDLL); //Calculo la direccion donde se escribirá el nombre de la dll
            
hLib = (LPTHREAD_START_ROUTINE)GetAddressAPIByName("Kernel32.dll""LoadLibraryA"); //Obtengo el puntero a la api LoadLibraryA

            
if(hLib){ //Si se obtuvo correctamente la direccion de LoadLibraryA
               
pDirCall = (unsigned long)hLib - (*pLoadDLL 5); //Calculo el valor a escribir para que el call apunte a esa api

               
if(WriteMemory(*pLoadDLLLoadDLLsizeof(LoadDLL))){ //Escribo el inline cargador en bruto
                  
if(WriteMemory(pNameDllDllNameNameDllLength)){ //Escribo el path de la dll
                     
if(WriteMemory(*pLoadDLL 2, &pNameDllsizeof(pNameDll))){ //Sobreescribo el push redirigiendolo a la direccion donde está el path
                        
if(WriteMemory(*pLoadDLL 7, &pDirCallsizeof(pDirCall))){ //Sobreescribo el call redirigiendolo al LoadLibraryA
                           
*BPLoadDll = *pLoadDLL 12//Calculo la direccion donde se colocará el BP de retorno
                           
if(SetBP(*BPLoadDll)){ //Coloco un BP detras del POPAD del codigo injertado
                              //Si llego hasta aqui es porque todo salió bien asi que cambio el valor de retorno
                              
ret true;
                              *
BackupEIPOnLoadDll GetEIP(); //Obtengo la direccion actual de EIP y la guardo para poder restaurarla cuando caiga en el BP
                              
SetEIP(*pLoadDLL); //Cambio EIP a la direccion donde he escrito el codigo de carga de dll
                           
}
                        }
                     }
                  }
               }
            }
         }
      }catch(...){
         
ret false;
      }

      if(
ret == false && *pLoadDLL != NULL){ //Si hubo algun problema
         //Libero la memoria allocada
         
VirtualFreeEx((HANDLE)GetHProcess(), (void*)*pLoadDLL0MEM_RELEASE); // Libero memoria

         //Elimino la direccion donde se obtuvo la memoria de la lista
         
ListapMemoriaAuxDllsInyectadas->Delete(ListapMemoriaAuxDllsInyectadas->Count 1);
         
delete pLoadDLL;

         
//Elimino la direccion del bp donde tendria que parar al cargar la dll de la lista
         
ListaBPsLoadDll->Delete(ListaBPsLoadDll->Count 1);
         
delete BPLoadDll;

         
//Elimino la direccion EIP donde retornaria al parar en el bp de la lista
         
ListaBackupEIPOnLoadDll->Delete(ListaBackupEIPOnLoadDll->Count 1);
         
delete BackupEIPOnLoadDll;
      }
   }
   return 
ret;

Funcion que inserta el codigo necesario para liberar una dll:
Código PHP:
bool __fastcall TDebugger::DeleteDLL(void *hLibModule)
{
   
BYTE UnloadDLL[] = {0x600x680x000x000x000x000xE80x000x000x000x000x610x90};
   
bool ret false;
   
LPTHREAD_START_ROUTINE hLib;
   
unsigned long pDirCall;

   
//Obtengo memoria para los punteros que irán a las listas
   
pUnloadDLL = new (std::nothrow)unsigned long;
   
BPUnloadDll = new (std::nothrow)unsigned long;
   
BackupEIPOnUnloadDll = new (std::nothrow)unsigned long;

   if(
pUnloadDLL == NULL || BPUnloadDll == NULL || BackupEIPOnUnloadDll == NULL)
   { 
//Si hubo algun problema
      
if(pUnloadDLL != NULL){ //Si se obtuvo memoria para esta, la libero
         
delete pUnloadDLL;
      }
      if(
BPUnloadDll == NULL){ //Si se obtuvo memoria para esta, la libero
         
delete BPUnloadDll;
      }
      if(
BackupEIPOnUnloadDll == NULL){ //Si se obtuvo memoria para esta, la libero
         
delete BackupEIPOnUnloadDll;
      }
   }else{ 
//Si no hubo error
      
try{
         
ListapMemoriaAuxDllsALiberar->Add(pUnloadDLL); //Añado la nueva direccion allocada a la lista de liberaciones
         
ListaBPsUnloadDll->Add(BPUnloadDll); //Añado el nuevo BP de salida a la lista de BPs de salida
         
ListaBackupEIPOnUnloadDll->Add(BackupEIPOnUnloadDll); //Añado la nueva direccion al nuevo EIP de retorno

         // Localizo memoria en el espacio de direcciones de la víctima
         
*pUnloadDLL = (unsigned long)VirtualAllocEx((HANDLE)GetHProcess(), NULLsizeof(UnloadDLL), MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);

         if(*
pUnloadDLL){ //Si se obtuvo memoria
            
hLib = (LPTHREAD_START_ROUTINE)GetAddressAPIByName("Kernel32.dll""FreeLibrary"); //Obtengo el puntero a la api FreeLibrary

            
if(hLib){ //Si se obtuvo correctamente la direccion de FreeLibrary
               
pDirCall = (unsigned long)hLib - (*pUnloadDLL 5); //Calculo el valor a escribir para que el call apunte a esa api

               
if(WriteMemory(*pUnloadDLLUnloadDLLsizeof(UnloadDLL))){ //Escribo el inline descargador en bruto
                  
if(WriteMemory(*pUnloadDLL 2, &hLibModulesizeof(hLibModule))){ //Sobreescribo el valor del push cambiandolo por el hModule de la dll a descargar
                     
if(WriteMemory(*pUnloadDLL 7, &pDirCallsizeof(pDirCall))){ //Sobreescribo el call redirigiendolo al FreeLibrary
                        
*BPUnloadDll = *pUnloadDLL 12//Calculo la direccion donde se colocará el BP de retorno
                        
if(SetBP(*BPUnloadDll)){ //Coloco un BP detras del POPAD del codigo injertado
                           //Si llego hasta aqui es porque todo salió bien asi que cambio el valor de retorno
                           
ret true;
                           *
BackupEIPOnUnloadDll GetEIP(); //Obtengo la direccion actual de EIP y la guardo para poder restaurarla cuando caiga en el BP
                           
SetEIP(*pUnloadDLL); //Cambio EIP a la direccion donde he escrito el codigo de descarga de dll
                        
}
                     }
                  }
               }
            }
         }
      }catch(...){
         
ret false;
      }

      if(
ret == false && *pUnloadDLL != NULL){ //Si hubo algun problema
         //Libero la memoria allocada
         
VirtualFreeEx((HANDLE)GetHProcess(), (void*)*pUnloadDLL0MEM_RELEASE); // Libero memoria

         //Elimino la direccion donde se obtuvo la memoria de la lista
         
ListapMemoriaAuxDllsALiberar->Delete(ListapMemoriaAuxDllsALiberar->Count 1);
         
delete pUnloadDLL;

         
//Elimino la direccion del bp donde tendria que parar al liberar la dll de la lista
         
ListaBPsUnloadDll->Delete(ListaBPsUnloadDll->Count 1);
         
delete BPUnloadDll;

         
//Elimino la direccion EIP donde retornaria al parar en el bp de la lista
         
ListaBackupEIPOnUnloadDll->Delete(ListaBackupEIPOnUnloadDll->Count 1);
         
delete BackupEIPOnUnloadDll;
      }
   }
   return 
ret;

Funcion modificada de gestion de los BPs:
Código PHP:
void __fastcall TDebugger::OnBreakpointDebugEvent(DWORD address)
{
   
bool IsLoadDll falseIsUnloadDll false//Estas dos variables son necesarias para saber si esta en una de las dos listas
   
int index//Esta variable es necesaria para trabajar con el elemento de la lista oportuna
   
unsigned long *pItemLista//Este es un puntero auxiliar que uso para trabajar con los items de las listas
   
try{
      
//Busco el valor de address en la lista de BPs de carga de dlls
      
for (index 0index ListaBPsLoadDll->Countindex++){
         
pItemLista = (unsigned long*)ListaBPsLoadDll->List[index];
         if((
unsigned long)*pItemLista == address){ //Si coinciden es porque ha parado al cargar la dll indicada
            
IsLoadDll true//Indico que se ha ejecutado ese codigo que carga la dll
            
break;
         }
      }
      if(!
IsLoadDll){ //Si no se encontró en la lista de carga de dlls
         //Busco el valor de address en la lista de BPs de liberación de dlls
         
for (index 0index ListaBPsUnloadDll->Countindex++){
            
pItemLista = (unsigned long*)ListaBPsUnloadDll->List[index];
            if((
unsigned long)*pItemLista == address){ //Si coinciden es porque ha parado al liberar la dll indicada
               
IsUnloadDll true//Indico que se ha ejecutado ese codigo que libera la dll
               
break;
            }
         }
      }

      if(
IsLoadDll == true)
      { 
//Si se encontró la direccion el la lista de bps de carga de dlls
         
RemoveBP((unsigned long)*pItemLista); //Desinstalo ese BP
         
delete ListaBPsLoadDll->List[index]; //Libero la memoria que almacena la direccion en la lista de bps de carga de dlls
         
ListaBPsLoadDll->Delete(index); //Elimino ese elemento de la lista de bps de carga de dlls

         
pItemLista = (unsigned long*)ListaBackupEIPOnLoadDll->List[index];
         
SetEIP((unsigned long)*pItemLista); //Restauro la direccion de EIP
         
delete ListaBackupEIPOnLoadDll->List[index]; //Libero la memoria que almacena la direccion en la lista de direcciones EIP
         
ListaBackupEIPOnLoadDll->Delete(index); //Elimino ese elemento de la lista de direcciones EIP

         
pItemLista = (unsigned long*)ListapMemoriaAuxDllsInyectadas->List[index];
         
VirtualFreeEx((HANDLE)GetHProcess(), (void*)*pItemLista0MEM_RELEASE); // Libero la memoria solicitada para esa carga de dll
         
delete ListapMemoriaAuxDllsInyectadas->List[index]; //Libero la memoria que almacena la direccion de la memoria solicitada para la carga de la dll
         
ListapMemoriaAuxDllsInyectadas->Delete(index); //Elimino ese elemento de la lista de direcciones de memorias allocadas
      
}
      else if(
IsUnloadDll == true)
      { 
//Si se encontró la direccion el la lista de bps de carga de dlls
         
RemoveBP((unsigned long)*pItemLista); //Desinstalo ese BP
         
delete ListaBPsUnloadDll->List[index]; //Libero la memoria que almacena la direccion en la lista de bps de liberación de dlls
         
ListaBPsUnloadDll->Delete(index); //Elimino ese elemento de la lista de bps de liberación de dlls

         
pItemLista = (unsigned long*)ListaBackupEIPOnUnloadDll->List[index];
         
SetEIP((unsigned long)*pItemLista); //Restauro la direccion de EIP
         
delete ListaBackupEIPOnUnloadDll->List[index]; //Libero la memoria que almacena la direccion en la lista de direcciones EIP
         
ListaBackupEIPOnUnloadDll->Delete(index); //Elimino ese elemento de la lista de direcciones EIP

         
pItemLista = (unsigned long*)ListapMemoriaAuxDllsALiberar->List[index];
         
VirtualFreeEx((HANDLE)GetHProcess(), (void*)*pItemLista0MEM_RELEASE); // Libero la memoria solicitada para esa liberacion de dll
         
delete ListapMemoriaAuxDllsALiberar->List[index]; //Libero la memoria que almacena la direccion de la memoria solicitada para la liberación de la dll
         
ListapMemoriaAuxDllsALiberar->Delete(index); //Elimino ese elemento de la lista de direcciones de memorias allocadas
      
}else    if(FuncBPs != NULL){ //Si no está en ninguna de las dos listas anteriores y existe una funcion para gestionar los BPs
         
FuncBPs(address); //Ejecutamos la funcion de gestion de BPs
        
}
   }catch(...){
   }

Luego para probarla hago esto en mi Unit1.cpp:
Variables globales:
Código PHP:
AnsiString dllInyectada "DLLHack.dll";
void *hDllHack NULL
Funcion para gestionar el evento OnEntryPoint:
Código PHP:
void __fastcall TFormMain::OnEntryPoint(DWORD Address)
{
   
bool error = !Depurador->InsertDLL(dllInyectada.c_str(),dllInyectada.Length());
}


Al cargarse las dlls voy buscando la que intento cargar y cuando la encuentro asigno los punteros a las funciones deseadas:
void __fastcall TFormMain::OnLoadDll(LOAD_DLL_DEBUG_INFO *info)
{
   if(
info->lpImageName != NULL)
   {
      
unsigned long dir;
      
AnsiString nombre;

      
//Obtenemos la direccion del puntero al path de la dll cargada
      
Depurador->ReadMemory((unsigned long)info->lpImageName,sizeof(dir),&dirsizeof(dir));

      
//Obtenemos el path completo de la dll
      
if(info->fUnicode != 0){
         
WideString aux Depurador->ReadUnicodeString(dir0);
         
nombre aux;
      }else{
         
nombre Depurador->ReadString(dir0);
      }

      
//Obtenemos el nombre de la dll
      
nombre ExtractFileName(nombre);

      
//No se porque pero si hago "if(nombre == dllInyectada)" aunque sean iguales no entra nunca pero con strcmp si entra
      
if(strcmp(nombre.c_str(), dllInyectada.c_str())== 0)
      { 
//Si es nuestra dll
         
hDllHack info->lpBaseOfDll//Necesario para poder liberar la dll cuando queramos

         //Obtengo los punteros de las funciones deseadas
         
pCopySelecteds = (LPTHREAD_START_ROUTINE)Depurador->GetAddressAPIByName("DLLHack.dll""CopySelecteds");
         
pPaste = (LPTHREAD_START_ROUTINE)Depurador->GetAddressAPIByName("DLLHack.dll""Paste");
         
pCopyAll = (LPTHREAD_START_ROUTINE)Depurador->GetAddressAPIByName("DLLHack.dll""CopyAll");
         
pSaveImageToFile = (LPTHREAD_START_ROUTINE)Depurador->GetAddressAPIByName("DLLHack.dll""SaveImageToFile");
         
pCopyImageToClipboard = (LPTHREAD_START_ROUTINE)Depurador->GetAddressAPIByName("DLLHack.dll""CopyImageToClipboard");
         
pSaveFile = (LPTHREAD_START_ROUTINE)Depurador->GetAddressAPIByName("DLLHack.dll""SaveFile");
      }
   }

Las siguientes dos lineas tendria que ponerlas en el evento donde quiera liberar la dll:
Código PHP:
Depurador->DeleteDLL(hDllHack);
hDllHack NULL
Si veis algo incorrecto por favor indicadmelo y ademas tengo la duda de por qué no funciona la comparacion que comento en el evento OnLoad que a ver si podeis aclararme por qué falla de una manera y no de la otra.
Gracias por adelantado.
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
Revision de printer.canvas cfernan Impresión 0 22-07-2010 16:40:11
Una Revision De Morfik, ASAPLTDA Debates 5 17-10-2008 19:16:27
Revision en segundo plano de una tabla paradox chrids506 Conexión con bases de datos 5 03-03-2007 18:37:51


La franja horaria es GMT +2. Ahora son las 05:44:37.


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