Nada, no doy con el modo de hacerlo.
Ahora mismo tengo el .h asi:
Código PHP:
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
#include <System.hpp>
//---------------------------------------------------------------------------
typedef struct {
UCHAR BeingDebugger;
UCHAR NTGlobalFlag;
UCHAR ProcessHeapFlags;
UCHAR ProcessHeapForceFlags;
}PEB_DETECTION;
PEB_DETECTION *ProtectPeb;
typedef struct {
WideString BeingDebugger;
WideString NTGlobalFlag;
WideString ProcessHeapFlags;
WideString ProcessHeapForceFlags;
WideString DebugPort;
WideString NtSetInformationThread;
WideString CloseHandleWithInvalidHandle;
WideString GetTickCount;
WideString timeGetTime;
WideString QueryPerformanceCounter;
WideString OutputDebugString;
}RETURN_DETECTION;
RETURN_DETECTION *Deteccion;
typedef struct { //Para truco con GetTickCount
DWORD TimeInit;
DWORD TimeEnd;
}sTimer;
typedef struct { //Para truco con QueryPerformanceCounter
__int64 TimeInit;
__int64 TimeEnd;
}sTimer64;
class TMyThread : public TThread
{
private:
sTimer gtc, tgt;
sTimer64 qpc;
protected:
void __fastcall Execute();
public:
__fastcall TMyThread(bool CreateSuspended,sTimer,sTimer,sTimer64);
void __fastcall ObtainStringsTimes(sTimer, sTimer, sTimer64);
void __fastcall ShowMessagesTimes(void);
};
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *ButtonPEB;
TMemo *MemoPEB;
TCheckBox *CheckBox1;
void __fastcall FormCreate(TObject *Sender);
void __fastcall ButtonPEBClick(TObject *Sender);
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
private: // User declarations
void __fastcall CheckDebug(void);
void __fastcall ObtenerDatosPEB(PEB_DETECTION *Peb_Protection);
void __fastcall QueryDetectionPEB(PEB_DETECTION *Peb_Protection, RETURN_DETECTION *Detection);
WideString __fastcall QueryDebugPortDetection(void);
WideString __fastcall QueryNtSetInformationThread(void);
bool __stdcall ObjectListCheck(RETURN_DETECTION *Detection);
WideString __fastcall CheckOutputDebugString(void);
public: // User declarations
PEB_DETECTION PEB_Protection;
RETURN_DETECTION Return_Detection;
sTimer gtc,tgt;
sTimer64 qpc;
class MyThread;
MyThread *hilo;
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
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(TComponent* Owner)
: TForm(Owner)
{
hilo=NULL;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ObtenerDatosPEB(PEB_DETECTION *Peb_Protection)
{
DWORD64 PEB;
DWORD64 read;
DWORD64 dwBeingDebugger, dwNTGlobalFlag, dwProcessHeapFlags, dwProcessHeapForceFlags;
//Obtengo el PEB
__asm
{
mov rax, gs:[0x60];
mov PEB, rax;
}
//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 ProcessHandle, ULONG ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength);
*(FARPROC *)&NtQueryInformationProcess = GetProcAddress(NtDll, "NtQueryInformationProcess");
HANDLE DebugPort;
status = NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort, &DebugPort, sizeof(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 ThreadHandle, ULONG ThreadInformationClass, PVOID ThreadInformation, ULONG 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_DETECTION *Peb_Protection, RETURN_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_ACP, 0, lpOutputString, -1, outputDebugStringBuffer, sizeof(outputDebugStringBuffer), 0, 0);
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(0x4001000A, 0, 4, args);//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)
{
ProtectPeb= new(PEB_DETECTION);
Deteccion = new(RETURN_DETECTION);
HANDLE hTrucho = (HANDLE)1234; //Para truco con CloseHandle
QueryPerformanceCounter((LARGE_INTEGER*)&qpc.TimeInit); //Obtenemos el tiempo inicial con QueryPerformanceCounter
tgt.TimeInit = timeGetTime();
gtc.TimeInit = GetTickCount(); //Obtenemos el tiempo inicial con GetTickCount
hilo = new TThread(true,gtc,tgt,qpc); //Creo un hilo para controlar el tiempo y poder pausar para probar el antiantidebug
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(ProtectPeb, Deteccion);
Deteccion->DebugPort = QueryDebugPortDetection();
//Deteccion->NtSetInformationThread = QueryNtSetInformationThread();
Deteccion->OutputDebugString = CheckOutputDebugString();
//Mostramos los datos
MemoPEB->Lines->Clear();
MemoPEB->Lines->Add(Deteccion->BeingDebugger + " Resultado = 0x"+WideString(IntToHex((int)ProtectPeb->BeingDebugger,2)));
MemoPEB->Lines->Add(Deteccion->NTGlobalFlag + " Resultado = 0x"+WideString(IntToHex((int)ProtectPeb->NTGlobalFlag,2)));
MemoPEB->Lines->Add(Deteccion->ProcessHeapFlags + " Resultado = 0x"+WideString(IntToHex((int)ProtectPeb->ProcessHeapFlags,2)));
MemoPEB->Lines->Add(Deteccion->ProcessHeapForceFlags + " Resultado = 0x"+WideString(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(tgt, gtc,qpc); //Obtengo los resultados
hilo->ShowMessagesTimes(); //Muestro los resultados
delete ProtectPeb;
delete Deteccion;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonPEBClick(TObject *Sender)
{
if(hilo != NULL)
delete hilo;
CheckDebug();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
if(hilo != NULL)
delete hilo;
}
//---------------------------------------------------------------------------
__fastcall TMyThread::TMyThread(bool CreateSuspended, sTimer sGetTickCount, sTimer sTimeGetTime, sTimer64 sQueryPerformanceCounter): TThread(CreateSuspended)
{
memcpy(>c,&sGetTickCount,sizeof(sTimer));
memcpy(&tgt,&sTimeGetTime,sizeof(sTimer));
memcpy(&qpc,&sQueryPerformanceCounter,sizeof(sTimer64));
}
//---------------------------------------------------------------------------
void __fastcall TMyThread::Execute()
{
Sleep(3000); //Necesario para comprobar si nos detectan por tiempo aunque asi nos detecte siempre
ObtainStringsTimes(tgt,gtc,qpc);
Synchronize(ShowMessagesTimes);
delete ProtectPeb;
delete Deteccion;
}
//---------------------------------------------------------------------------
void __fastcall TMyThread::ShowMessagesTimes()
{
//Mostramos si nos ha detectado con GetTickCount o no y posicionamos al inicio el TMEMO
Form1->MemoPEB->Lines->Add(Deteccion->GetTickCount);
Form1->MemoPEB->Lines->Add(Deteccion->timeGetTime);
Form1->MemoPEB->Lines->Add(Deteccion->QueryPerformanceCounter);
Form1->MemoPEB->SelStart=0;
Form1->MemoPEB->SelLength = 0;
Form1->MemoPEB->Perform(EM_SCROLLCARET, 0,(__int64) 0);
}
//---------------------------------------------------------------------------
void __fastcall TMyThread::ObtainStringsTimes(sTimer tgc, sTimer gtc,sTimer64 qpc)
{
__int64 frec=0;
gtc.TimeEnd = GetTickCount(); //Obtenemos el tiempo final con GetTickCount
tgc.TimeEnd = timeGetTime(); //Obtenemos el tiempo final con timeGetTime
QueryPerformanceCounter((LARGE_INTEGER*)&(qpc.TimeEnd)); //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((gtc.TimeEnd - gtc.TimeInit) > 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((tgc.TimeEnd - tgc.TimeInit) > 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((qpc.TimeEnd - qpc.TimeInit)/(frec/1000) > 2000)
{
Deteccion->QueryPerformanceCounter = "Detectado con método QueryPerformanceCounter.";
}else{
Deteccion->QueryPerformanceCounter = "No detectado con método QueryPerformanceCounter.";
}
}
//---------------------------------------------------------------------------
y los errores:
Código:
[bcc64 Error] Unit1.cpp(192): 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(222): member access into incomplete type 'TForm1::MyThread'
Unit1.h(85): forward declaration of 'TForm1::MyThread'
[bcc64 Error] Unit1.cpp(224): member access into incomplete type 'TForm1::MyThread'
Unit1.h(85): forward declaration of 'TForm1::MyThread'
[bcc64 Error] Unit1.cpp(225): member access into incomplete type 'TForm1::MyThread'
Unit1.h(85): forward declaration of 'TForm1::MyThread'
[bcc64 Warning] Unit1.cpp(237): deleting pointer to incomplete type 'TForm1::MyThread' may cause undefined behavior
Unit1.h(85): forward declaration of 'TForm1::MyThread'
[bcc64 Warning] Unit1.cpp(245): deleting pointer to incomplete type 'TForm1::MyThread' may cause undefined behavior
Unit1.h(85): forward declaration of 'TForm1::MyThread'
¿alguien puede ayudarme?
|