Ver Mensaje Individual
  #1  
Antiguo 28-05-2020
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Reputación: 14
aguml Va por buen camino
Hilo anidado en la clase

Hola amigos, tengo un problemilla, estoy con una pequeña tool la cual usa trucos antidebug y funcionaba muy bien pero el caso es que para las detecciones por tiempo tenia un Sleep el cual me congelaba el formulario por lo que he decidido meterlo en un hilo y ahí empezaron todos mis problemas.
La cabecera la tengo así:
Código PHP:
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
//---------------------------------------------------------------------------

class TForm1 : public TForm
{
__published:    // IDE-managed Components
        
TButton *ButtonPEB;
        
TMemo *MemoPEB;
        
TCheckBox *CheckBox1;
        
void __fastcall FormCreate(TObject *Sender);
        
void __fastcall ButtonPEBClick(TObject *Sender);
private:    
// User declarations
        
typedef struct _PEB_Protection{
                
UCHAR BeingDebugger;
                
UCHAR NTGlobalFlag;
                
UCHAR ProcessHeapFlags;
                
UCHAR ProcessHeapForceFlags;
        }
PEB_Protection;

        
typedef struct _Return_Detection{
                
WideString BeingDebugger;
                
WideString NTGlobalFlag;
                
WideString ProcessHeapFlags;
                
WideString ProcessHeapForceFlags;
                
WideString DebugPort;
                
WideString NtSetInformationThread;
                
WideString CloseHandleWithInvalidHandle;
                
WideString GetTickCount;
                
WideString timeGetTime;
                
WideString QueryPerformanceCounter;
                
WideString OutputDebugString;
        }
Return_Detection;

        
void __fastcall CheckDebug(void);
        
void __fastcall ObtenerDatosPEB(PEB_Protection *Peb_Protection);
        
void __fastcall QueryDetectionPEB(PEB_Protection *Peb_ProtectionReturn_Detection *Detection);
        
WideString __fastcall QueryDebugPortDetection(void);
        
WideString __fastcall QueryNtSetInformationThread(void);
        
bool __stdcall ObjectListCheck(Return_Detection *Detection);
        
WideString __fastcall CheckOutputDebugString(void);
public:        
// User declarations
        
DWORD TimeInitGTCTimeEndGTC//Para truco con GetTickCount
        
DWORD TimeInitTGTTimeEndTGT//Para truco con timeGetTime
        
__int64 TimeInitQPC=0TimeEndQPC=0frec=0//Para truco con QueryPerformanceCounter
        
Return_Detection *Deteccion;

        class 
TMyThread : public TThread
        
{
            private:
                
void __fastcall ShowMessages();
            protected:
                
virtual void __fastcall Execute();
            public:
                
__fastcall TMyThread(bool CreateSuspended);
                
void __fastcall ObtainStringsTimes(void);
                
void __fastcall ShowMessagesTimes(void);
        };

        
__fastcall TForm1(TComponentOwner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif 
Y el .cpp:
Código PHP:
//---------------------------------------------------------------------------

#include <vcl.h>
#include <Windows.h>
#include <Mmsystem.h>
#include <winnt.h>
#pragma hdrstop

#include "Unit1.h"

#define ObjectAllInformation 3
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponentOwner)
        : 
TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ObtenerDatosPEB(PEB_Protection *Peb_Protection)
{
    
DWORD64 PEB;
    
DWORD64 read;
    
DWORD64 dwBeingDebuggerdwNTGlobalFlagdwProcessHeapFlagsdwProcessHeapForceFlags;

    
//Obtengo el PEB
    
__asm
    
{
        
mov raxgs:[0x60];
        
mov PEBrax;
    }

    
//Obtenemos el valor de BeingDebugger
    
dwBeingDebugger PEB+0x2;
    
ReadProcessMemory(GetCurrentProcess(),(LPVOID)dwBeingDebugger,&Peb_Protection->BeingDebugger ,sizeof(Peb_Protection->BeingDebugger),(DWORD64*)&read);

    
//Obtenemos el valor de NtGlobalFlag

    
dwNTGlobalFlag PEB+0xBC;
    
ReadProcessMemory(GetCurrentProcess(),(LPVOID)dwNTGlobalFlag,&Peb_Protection->NTGlobalFlag,sizeof(Peb_Protection->NTGlobalFlag),(DWORD64*)&read);

    
//Obtenemos el valor de ProcessHeapFlags
    
ReadProcessMemory(GetCurrentProcess(),(LPVOID)(PEB+0x30),&dwProcessHeapFlags ,sizeof(dwProcessHeapFlags),(DWORD64*)&read);
    
dwProcessHeapFlags += 0x70;
    
ReadProcessMemory(GetCurrentProcess(),(LPVOID)(dwProcessHeapFlags),&Peb_Protection->ProcessHeapFlags ,sizeof(Peb_Protection->ProcessHeapFlags),(DWORD64*)&read);

    
//Obtenemos el valor de ProcessHeapForceFlags
    
ReadProcessMemory(GetCurrentProcess(),(LPVOID)(PEB+0x30),&dwProcessHeapForceFlags ,sizeof(dwProcessHeapForceFlags),(DWORD64*)&read);
    
dwProcessHeapForceFlags += 0x74;
    
ReadProcessMemory(GetCurrentProcess(),(LPVOID)(dwProcessHeapForceFlags),&Peb_Protection->ProcessHeapForceFlags ,sizeof(Peb_Protection->ProcessHeapForceFlags),(DWORD64*)&read);
}
//---------------------------------------------------------------------------

WideString __fastcall TForm1::QueryDebugPortDetection(void)
{
        
ULONG ProcessDebugPort 7;
        
DWORD read;
        
HMODULE NtDll;
        
ULONG status;
        
WideString retval;

        
NtDll LoadLibrary(L"ntdll.dll");
        
LONG (WINAPI *NtQueryInformationProcess)(HANDLE ProcessHandleULONG ProcessInformationClassPVOID ProcessInformationULONG ProcessInformationLengthPULONG ReturnLength);
        *(
FARPROC *)&NtQueryInformationProcess GetProcAddress(NtDll"NtQueryInformationProcess");

        
HANDLE DebugPort;
        
status NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort, &DebugPortsizeof(DebugPort), &read);

        if(
DebugPort)
        {
                
retval "DebugPort te ha detectado.";
        }
        else
        {
                
retval "DebugPort no te ha detectado.";
        }
        return 
retval;
}
//---------------------------------------------------------------------------

WideString __fastcall TForm1::QueryNtSetInformationThread(void)
{
        
HMODULE NtDll;
        
ULONG status;
        
WideString retval;
        
int ThreadHideFromDebugger 0x11;
        
DWORD ThreadInfo;
        
NtDll LoadLibrary(L"ntdll.dll");
        
LONG (WINAPI *NtSetInformationThread)(HANDLE ThreadHandleULONG ThreadInformationClassPVOID ThreadInformationULONG ThreadInformationLength);
        *(
FARPROC *)&NtSetInformationThread GetProcAddress(NtDll"NtSetInformationThread");

        
status NtSetInformationThread(GetCurrentThread(),ThreadHideFromDebugger,0,0);

        if(
status == 0)
        {
                
retval "NtSetInformationThread pasado con éxito.";
        }else{
                
retval "NtSetInformationThread nos ha desatacheado.";
        }
        return 
retval;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::QueryDetectionPEB(PEB_Protection *Peb_ProtectionReturn_Detection *Detection)
{
        
ObtenerDatosPEB(Peb_Protection);

        if(
Peb_Protection->BeingDebugger == 0x1)
        {
                
Detection->BeingDebugger "BeingDebugger te ha detectado.";
        }else{
                
Detection->BeingDebugger "BeingDebugger no te ha detectado.";
        }

        if(
Peb_Protection->NTGlobalFlag == 0x70)
        {
                
Detection->NTGlobalFlag "NtGlobalFlag te ha detectado.";
        }else{
                
Detection->NTGlobalFlag "NtGlobalFlag no te ha detectado.";
        }

        if(
Peb_Protection->ProcessHeapFlags != 2)
        {
                
Detection->ProcessHeapFlags "ProcessHeapFlags te ha detectado.";
        }else{
                
Detection->ProcessHeapFlags "ProcessHeapFlags no te ha detectado.";
        }

        if(
Peb_Protection->ProcessHeapForceFlags != 0)
        {
                
Detection->ProcessHeapForceFlags "ProcessHeapForceFlags te ha detectado.";
        }else{
                
Detection->ProcessHeapForceFlags "ProcessHeapForceFlags no te ha detectado.";
        }
}
//---------------------------------------------------------------------------
WideString __fastcall TForm1::CheckOutputDebugString(void)
{
    
wchar_t lpOutputString[]=L"Hello Debugger!";
    
char outputDebugStringBuffer[1000] = {0};
    
WideString retval;

    
WideCharToMultiByte(CP_ACP0lpOutputString, -1outputDebugStringBuffersizeof(outputDebugStringBuffer), 00);

    
ULONG_PTR args[4];

    
//unicode
    
args[0] = (ULONG_PTR)wcslen(lpOutputString) + 1;
    
args[1] = (ULONG_PTR)lpOutputString;

    
//ansi for compatibility
    
args[2] = (ULONG_PTR)wcslen(lpOutputString) + 1;
    
args[3] = (ULONG_PTR)outputDebugStringBuffer;

    
__try
    
{
        
RaiseException(0x4001000A04args);//DBG_PRINTEXCEPTION_WIDE_C
        
retval "Debugger detectado con OutputDebugString.";
    }
    
__except(EXCEPTION_EXECUTE_HANDLER)
    {
        
retval "Debugger no detectado con OutputDebugString.";
    }

    return 
retval;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
        
CheckDebug();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::CheckDebug(void)
{
        
PEB_Protection *ProtectPeb= new(PEB_Protection);
        
Deteccion = new(Return_Detection);
        
HANDLE hTrucho = (HANDLE)1234//Para truco con CloseHandle
        
TMyThread *hilo = (TMyThread*) new TThread(true);

        
QueryPerformanceCounter((LARGE_INTEGER*)&TimeInitQPC); //Obtenemos el tiempo inicial con QueryPerformanceCounter
        
TimeInitTGT timeGetTime();
        
TimeInitGTC GetTickCount(); //Obtenemos el tiempo inicial con GetTickCount

        
if(ProtectPeb != NULL && Deteccion != NULL)
        {
                
Deteccion->CloseHandleWithInvalidHandle "No detectado por CloseHandle con un handle inválido.";

                
__try{
                        
CloseHandle(hTrucho);
                }
                
__except(EXCEPTION_EXECUTE_HANDLER){
                        
Deteccion->CloseHandleWithInvalidHandle "Detectado por CloseHandle con un handle inválido.";
                }

                
QueryDetectionPEB(ProtectPebDeteccion);
                
Deteccion->DebugPort QueryDebugPortDetection();
                
//Deteccion->NtSetInformationThread = QueryNtSetInformationThread();
                
Deteccion->OutputDebugString CheckOutputDebugString();

                
//Mostramos los datos
                
MemoPEB->Lines->Clear();
                
MemoPEB->Lines->Add(Deteccion->BeingDebugger " Resultado = 0x"+AnsiString(IntToHex((int)ProtectPeb->BeingDebugger,2)));
                
MemoPEB->Lines->Add(Deteccion->NTGlobalFlag " Resultado = 0x"+AnsiString(IntToHex((int)ProtectPeb->NTGlobalFlag,2)));
                
MemoPEB->Lines->Add(Deteccion->ProcessHeapFlags +  " Resultado = 0x"+AnsiString(IntToHex((int)ProtectPeb->ProcessHeapFlags,2)));
                
MemoPEB->Lines->Add(Deteccion->ProcessHeapForceFlags " Resultado = 0x"+AnsiString(IntToHex((int)ProtectPeb->ProcessHeapForceFlags,2)));
                
MemoPEB->Lines->Add(Deteccion->DebugPort);
                
MemoPEB->Lines->Add(Deteccion->CloseHandleWithInvalidHandle);
                
MemoPEB->Lines->Add(Deteccion->NtSetInformationThread);
                
MemoPEB->Lines->Add(Deteccion->OutputDebugString);
        }
        if(
CheckBox1->Checked == true)
            
hilo->Resume();
        else{
            
hilo->ObtainStringsTimes(); //Obtengo los resultados
            
hilo->ShowMessagesTimes(); //Muestro los resultados
            
delete ProtectPeb;
            
delete Deteccion;
        }


}
//---------------------------------------------------------------------------

__fastcall TMyThread::TMyThread(bool CreateSuspended): TThread(CreateSuspended)
{

}
//---------------------------------------------------------------------------

void __fastcall TMyThread::ShowMessagesTimes()
{
    
//Mostramos si nos ha detectado con GetTickCount o no y posicionamos al inicio el TMEMO
    
MemoPEB->Lines->Add(Deteccion->GetTickCount);
    
MemoPEB->Lines->Add(Deteccion->timeGetTime);
    
MemoPEB->Lines->Add(Deteccion->QueryPerformanceCounter);
    
MemoPEB->SelStart=0;
    
MemoPEB->SelLength 0;
    
MemoPEB->Perform(EM_SCROLLCARET0,(__int640);
}
//---------------------------------------------------------------------------

void __fastcall TMyThread::ObtainStringsTimes()
{
    
TimeEndGTC GetTickCount(); //Obtenemos el tiempo final con GetTickCount
    
TimeEndTGT timeGetTime(); //Obtenemos el tiempo final con timeGetTime
    
QueryPerformanceCounter((LARGE_INTEGER*)&TimeEndQPC); //Obtenemos el tiempo final con QueryPerformanceCounter

    //Obtenemos la frecuencia
    
QueryPerformanceFrequency((LARGE_INTEGER*)&frec);

    
//Aqui comprobamos que el tiempo transcurrido no pase de 2 segundos en milisegundos
    
if((TimeEndGTC TimeInitGTC) > 2000)
    {
            
Deteccion->GetTickCount "Detectado con método GetTickCount.";
    }else{
            
Deteccion->GetTickCount "No detectado con método GetTickCount.";
    }

    
//Aqui comprobamos que el tiempo transcurrido usando timeGetTime no pase de 2 segundos en milisegundos
    
if((TimeEndTGT TimeInitTGT) > 2000)
    {
            
Deteccion->timeGetTime "Detectado con método timeGetTime.";
    }else{
            
Deteccion->timeGetTime "No detectado con método timeGetTime.";
    }

    
//Aqui comprobamos que el tiempo transcurrido usando QueryPerformanceCounter no pase de 2 segundos en milisegundos
    
if((TimeEndQPC TimeInitQPC)/(frec/1000) > 2000)
    {
            
Deteccion->QueryPerformanceCounter "Detectado con método QueryPerformanceCounter.";
    }else{
            
Deteccion->QueryPerformanceCounter "No detectado con método QueryPerformanceCounter.";
    }

}
//---------------------------------------------------------------------------

void __fastcall TMyThread::Execute()
{

    
Sleep(3000); //Necesario para comprobar si nos detectan por tiempo aunque asi nos detecte siempre
    
ObtainStringsTimes();
    
Synchronize(ShowMessages);
    
delete ProtectPeb;
    
delete Deteccion;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonPEBClick(TObject *Sender)
{
        
CheckDebug();
}
//--------------------------------------------------------------------------- 
Y esto chilla por todas partes, sobre todo con las declaraciones de los metodos de la clase del hilo que no se como se tienen que declarar cuando están anidadas y tambien falla al intentar crear el hilo.
Código:
[bcc64 Error] Unit1.cpp(185): allocating an object of abstract class type 'System::Classes::TThread'
  System.Classes.hpp(2624): unimplemented pure virtual method 'Execute' in 'TThread'
[bcc64 Error] Unit1.cpp(231): use of undeclared identifier 'TMyThread'
[bcc64 Error] Unit1.cpp(231): C++ requires a type specifier for all declarations
[bcc64 Error] Unit1.cpp(231): only constructors take base initializers
[bcc64 Error] Unit1.cpp(237): expected a class or namespace
[bcc64 Error] Unit1.cpp(249): expected a class or namespace
[bcc64 Error] Unit1.cpp(285): expected a class or namespace
Responder Con Cita