Funcion calloc() en vb.net?

Iniciado por **Aincrad**, 10 Mayo 2019, 16:08 PM

0 Miembros y 1 Visitante están viendo este tema.

**Aincrad**

Hola, bueno como dice el titulo, no encuentro como declarar esa funcion en vb.net. espero que me puedan ayudar gracias de antemano, la necesito para este code :

Código (vbnet) [Seleccionar]
<DllImport("msvcrt.dll", EntryPoint:="memcpy", CallingConvention:=CallingConvention.Cdecl)> _
   Public Shared Sub CopyMemory(ByVal dest As IntPtr, ByVal src As IntPtr, ByVal count As Integer)
   End Sub



   Private Function GetMutexString() As String

       Dim lpMutexStr As String = calloc(64, 1)
       Dim s() As Byte = {&H98, &H9B, &H99, &H9D, &HC3, &H15, &H6F, &H6F, &H2D, &HD3, &HEA, &HAE, &H13, &HFF, &H7A, &HBE, &H63, &H36, &HFC, &H63, &HF3, &H74, &H32, &H74, &H71, &H72, &H4E, &H2, &H81, &H1E, &H19, &H20, &H44, &HDF, &H81, &HD7, &H15, &H92, &H93, &H1A, &HE7}
       Dim Sizes As Integer = Marshal.SizeOf(s(0)) * s.Length
       Dim pnt1 As IntPtr = Marshal.AllocHGlobal(Sizes)
       Dim m As UInteger = 0
       Do While m < Len(s)
           Dim c As Byte = s(m)
           c -= &HE8
           c = ((c >> &H5) Or (c << &H3))
           c = -c
           c += &H51
           c = Not c
           c -= &H93
           c = ((c >> &H3) Or (c << &H5))
           c += &H14
           c = c Xor &H14
           c = ((c >> &H1) Or (c << &H7))
           c = c Xor &HD3
           c += m
           c = Not c
           c = ((c >> &H5) Or (c << &H3))
           c -= &H2B
           s(m) = c
           m += 1
       Loop

       CopyMemory(lpMutexStr, pnt1, Len(s))
       Return lpMutexStr
   End Function


Intento pasar este code de Anti-Debug a VB.NET .

Código (cpp) [Seleccionar]
#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include <psapi.h>

typedef enum { ThreadHideFromDebugger = 0x11 } THREADINFOCLASS;

typedef NTSTATUS(WINAPI *NtQueryInformationThread_t)(HANDLE, THREADINFOCLASS, PVOID, ULONG, PULONG);
typedef NTSTATUS(WINAPI *NtSetInformationThread_t)(HANDLE, THREADINFOCLASS, PVOID, ULONG);

VOID ThreadMain(LPVOID p);
LPSTR GetMutexString();

VOID WINAPI init_antidbg(PVOID DllHandle, DWORD Reason, PVOID Reserved)
{
    //Deobfuscate our mutex and lock it so our child doesnt execute this TLS callback.
    unsigned char s[] =
    {

        0x9d, 0x3, 0x3c, 0xec, 0xf0, 0x8b, 0xb5, 0x5,
        0xe2, 0x2a, 0x87, 0x5, 0x64, 0xe4, 0xf8, 0xe7,
        0x64, 0x29, 0xd2, 0x6, 0xad, 0x29, 0x9a, 0xe0,
        0xea, 0xf9, 0x2, 0x7d, 0x31, 0x72, 0xf7, 0x33,
        0x13, 0x83, 0xb, 0x8f, 0xae, 0x2c, 0xa7, 0x2a,
        0x95
    };

    for (unsigned int m = 0; m < sizeof(s); ++m)
    {
        unsigned char c = s[m];
        c = (c >> 0x7) | (c << 0x1);
        c ^= m;
        c = (c >> 0x5) | (c << 0x3);
        c += 0xa9;
        c = ~c;
        c += 0xd6;
        c = -c;
        c += m;
        c = ~c;
        c = (c >> 0x5) | (c << 0x3);
        c -= m;
        c = ~c;
        c += m;
        c ^= m;
        c += m;
        s[m] = c;
    }

    HANDLE hMutex = CreateMutexA(NULL, TRUE, s);

    // We don't want to empty the working set of our child process, it's not neccessary as it has a debugger attached already.
    if (GetLastError() == ERROR_ALREADY_EXISTS)
    {
        return;
    }

    /*
        CODE DESCRIPTION:
        The following code is reponsible for preventing the debugger to attach on parent process at runtime.
    */
    SIZE_T min, max;
    SYSTEM_INFO si = { 0 };

    GetSystemInfo(&amp;si);

    K32EmptyWorkingSet(GetCurrentProcess());

    void *p = NULL;
    while (p = VirtualAllocEx(GetCurrentProcess(), NULL, si.dwPageSize, MEM_COMMIT | MEM_RESERVE, PAGE_NOACCESS))
    {
        if (p == NULL)
            break;
    }
    /*
        DESCRIPTION END
    */


    /*
        CODE DESCRIPTION:
        The following code is responsible for handling the application launch inside a debbuger and invoking a crash.
    */
    NtQueryInformationThread_t fnNtQueryInformationThread = NULL;
    NtSetInformationThread_t fnNtSetInformationThread = NULL;

    DWORD dwThreadId = 0;
    HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadMain, NULL, 0, 0, &amp;dwThreadId);

    HMODULE hDLL = LoadLibrary("ntdll.dll");
    if (!hDLL) return -1;

    fnNtQueryInformationThread = (NtQueryInformationThread_t)GetProcAddress(hDLL, "NtQueryInformationThread");
    fnNtSetInformationThread = (NtSetInformationThread_t)GetProcAddress(hDLL, "NtSetInformationThread");

    if (!fnNtQueryInformationThread || !fnNtSetInformationThread)
        return -1;

    ULONG lHideThread = 1, lRet = 0;

    fnNtSetInformationThread(hThread, ThreadHideFromDebugger, &amp;lHideThread, sizeof(lHideThread));
    fnNtQueryInformationThread(hThread, ThreadHideFromDebugger, &amp;lHideThread, sizeof(lHideThread), &amp;lRet);
    /*
        DESCRIPTION END
    */
}


// Usually what happens is that person who does the analysis doesn't have a breakpoint set for TLS.
// (It's not set ON by default in x64dbg)
#pragma comment(linker, "/INCLUDE:__tls_used") // We want to include TLS Data Directory structure in our program
#pragma data_seg(push)
#pragma data_seg(".CRT$XLAA")
EXTERN_C PIMAGE_TLS_CALLBACK p_tls_callback1 = init_antidbg; // This will execute before entry point and main function.
#pragma data_seg(pop)


int main(int argc, char *argv[])
{
    // Beging by deobfuscating our mutex.
    HANDLE hMutex = CreateMutexA(NULL, TRUE, GetMutexString());

    if (GetLastError() == ERROR_ALREADY_EXISTS) {
        // We are a spawn, run normally
        printf("[+] Normal execution.\n");
        getchar();
        return 0;
    }
    else {
        // We are the first instance
        TCHAR szFilePath[MAX_PATH] = { 0 };
        GetModuleFileName(NULL, szFilePath, MAX_PATH);

        PROCESS_INFORMATION pi = { 0 };
        STARTUPINFO si = { 0 };
        si.cb = sizeof(STARTUPINFO);

        // Create child process
        CreateProcess(szFilePath, NULL, NULL, NULL, FALSE, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | CREATE_NEW_CONSOLE, 0, NULL, &amp;si, &amp;pi);
        if (pi.hProcess != NULL) {
            printf("[+] Spawning child process and attaching as a debugger.\n");

            // Debug event
            DEBUG_EVENT de = { 0 };
            while (1)
            {
                WaitForDebugEvent(&amp;de, INFINITE);
                // We only care about when the process terminates
                if (de.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
                    break;
                // Otherwise ignore all other events
                ContinueDebugEvent(pi.dwProcessId, pi.dwThreadId, DBG_CONTINUE);
            }
        }

        CloseHandle(pi.hProcess);
        CloseHandle(hMutex);
    }

    return 0;
}

LPSTR GetMutexString()
{
    LPSTR lpMutexStr = calloc(64, 1);
    unsigned char s[] =
    {

        0x98, 0x9b, 0x99, 0x9d, 0xc3, 0x15, 0x6f, 0x6f,
        0x2d, 0xd3, 0xea, 0xae, 0x13, 0xff, 0x7a, 0xbe,
        0x63, 0x36, 0xfc, 0x63, 0xf3, 0x74, 0x32, 0x74,
        0x71, 0x72, 0x4e, 0x2, 0x81, 0x1e, 0x19, 0x20,
        0x44, 0xdf, 0x81, 0xd7, 0x15, 0x92, 0x93, 0x1a,
        0xe7
    };

    for (unsigned int m = 0; m < sizeof(s); ++m)
    {
        unsigned char c = s[m];
        c -= 0xe8;
        c = (c >> 0x5) | (c << 0x3);
        c = -c;
        c += 0x51;
        c = ~c;
        c -= 0x93;
        c = (c >> 0x3) | (c << 0x5);
        c += 0x14;
        c ^= 0x14;
        c = (c >> 0x1) | (c << 0x7);
        c ^= 0xd3;
        c += m;
        c = ~c;
        c = (c >> 0x5) | (c << 0x3);
        c -= 0x2b;
        s[m] = c;
    }
    memcpy(lpMutexStr, s, sizeof(s));
    return lpMutexStr;
}

VOID ThreadMain(LPVOID p)
{
    while (1)
    {
        if (IsDebuggerPresent())
        {
            __asm { int 3; }
        }
        Sleep(500);
    }
    return 0;
}
}




Eleкtro

#1
Según la documentación de Microsoft, el propósito de la función calloc es asignar un array de tamaño específico, e inicializar todos sus elementos a cero...

Cita de: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/calloc?view=vs-2019calloc | Microsoft Docs
Allocates an array in memory with elements initialized to 0.

Por lo tanto, es innecesario reproducir esta función, ya que en .NET no es necesario administrar manualmente la memoria para el propósito que tu quieres llevar a cabo.

De todas formas, un equivalente cercano en VB.NET sería usar el siguiente tipo de declaración, con la obvia diferencia de que esto asignaría el array en la memoria administrada...

Código (vbnet) [Seleccionar]
Dim chars(63) As Char

Ten en cuenta que referente a la asignación en la memoria no administrada, siempre puedes utilizar la función Marshal.AlllocHGlobal().




El propósito de la función GetMutexString es devolver el nombre de un Mutex de 64 caracteres (lo cual es muy arbitrario, bien podrían ser 10, 20, o 128 caracteres), por lo que perfectamente puedes simplificar todo ese código de C/C++ a una simple declaración de String en lugar de declarar un array de caracteres...

Código (vbnet) [Seleccionar]
Dim mutexName As String = "Global\Nombre del mutex" ' Global\Name or Local\Name

O si quieres generar un nombre aleatorio de X caracteres, puedes hacerlo así:
Código (vbnet) [Seleccionar]
Dim mutexName As New StringBuilder()
mutexName.Append("Global\") ' Global\Name or Local\Name

For i As Integer = 0 To (16 - 1)
   mutexName.Append(Convert.ToChar(RNG.Next(65, 91))) ' A to Z virtual-keys.
Next


Si quieres añadir alguna medida de ofuscación, eso ya sería decisión tuya.




Y ten en cuenta también la existencia de la clase System.Threading.Mutex para crear un mutex mediante código administrado...

Código (vbnet) [Seleccionar]

Dim mtxACL As New MutexAccessRule(New SecurityIdentifier(WellKnownSidType.WorldSid, Nothing), MutexRights.FullControl, AccessControlType.Allow)
Dim mtxSecurity As New MutexSecurity()
mtxSec.AddAccessRule(mtxACL)

Dim mtx As New Mutex(True, mutexName, New Boolean, mtxSec)


Saludos.








**Aincrad**

Gracias por responder, me has ayudado xd.

una Pregunta. hay alguna manera facil de declarar codigo ASM en vb.net?

Por ejemplo en esta funcion :

Código (cpp) [Seleccionar]
VOID ThreadMain(LPVOID p)
{
    while (1)
    {
        if (IsDebuggerPresent())
        {
            __asm { int 3; }
        }
        Sleep(500);
    }
    return 0;
}


No encontre como declarar codigo ASM en vb.net, en la parte :

Código (cpp) [Seleccionar]
__asm { int 3; }

Bueno al final lo hice asi :

Código (vbnet) [Seleccionar]

Private Declare Function IsDebuggerPresent Lib "kernel32" () As Integer

Private Function IsDebuggerPresentFunc() As Boolean
        If IsDebuggerPresent = 1 Then
            Return True
        End If
        Return False
    End Function





Eleкtro

#3
Actualiza tus P/Invokes...

Código (vbnet) [Seleccionar]
Friend NotInheritable Class NativeMethods

   Private Sub New()
   End Sub

   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' Determines whether the calling process is being debugged by a user-mode debugger.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   ''' <remarks>
   ''' <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms680345(v=vs.85).aspx"/>
   ''' </remarks>
   ''' ----------------------------------------------------------------------------------------------------
   ''' <returns>
   ''' If the current process is running in the context of a debugger, the return value is <see langword="True"/>.
   ''' <para></para>
   ''' If the current process is not running in the context of a debugger, the return value is <see langword="False"/>.
   ''' </returns>
   ''' ----------------------------------------------------------------------------------------------------
   <DllImport("Kernel32.dll", SetLastError:=False)>
   Friend Shared Function IsDebuggerPresent(
   ) As <MarshalAs(UnmanagedType.Bool)> Boolean
   End Function

End Class


Y recuerda que también puedes utilizar la propiedad System.Diagnostics.Debugger.IsAttached para el debugger de Visual Studio. Aunque me imagino que eso no es lo que buscas...





En fin. Te muestro un modo en como lo puedes hacer...

( El siguiente código ha sido extraido de forma gratuita de la librería comercial DevCase for .NET Framework para desarrolladores de .NET )

DebuggerNotify.vb
Código (vbnet) [Seleccionar]
#Region " Imports "

Imports System
Imports System.Timers

#End Region

#Region " Usage Examples "

' Public Class Form1
'
'     Private WithEvents DebuggerNotify As DebuggerNotify
'
'     Public Sub New()
'         MyClass.InitializeComponent()
'         Me.DebuggerNotify = New DebuggerNotify()
'     End Sub
'
'     Private Sub DebuggerNotify_StatusChanged(ByVal sender As Object, ByVal e As DebuggerNotifyEventArgs) Handles DebuggerNotify.StatusChanged
'         Dim msg As String = $"Debugger status changed to {NameOf(e.IsAttached)}: {e.IsAttached}"
'         Console.WriteLine(msg)
'     End Sub
'
' End Class

#End Region

#Region " DebuggerNotify "

Namespace DevCase.Core.Diagnostics.Debug

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Provides a mechanism to notify when a debugger in user-mode is attached to or detached from the current process.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <example> This is a code example.
    ''' <code>
    ''' Public Class Form1
    '''
    '''     Private WithEvents DebuggerNotify As DebuggerNotify
    '''
    '''     Public Sub New()
    '''         MyClass.InitializeComponent()
    '''         Me.DebuggerNotify = New DebuggerNotify()
    '''     End Sub
    '''
    '''     Private Sub DebuggerNotify_StatusChanged(ByVal sender As Object, ByVal e As DebuggerNotifyEventArgs) Handles DebuggerNotify.StatusChanged
    '''         Dim msg As String = $"Debugger status changed to {NameOf(e.IsAttached)}: {e.IsAttached}"
    '''         Console.WriteLine(msg)
    '''     End Sub
    '''
    ''' End Class
    ''' </code>
    ''' </example>
    ''' ----------------------------------------------------------------------------------------------------
    Public Class DebuggerNotify : Implements IDisposable

#Region " Private Fields "

        ''' ----------------------------------------------------------------------------------------------------
        ''' <summary>
        ''' A <see cref="Timer"/> that periodically checks for the presence of a debugger attached to the current process.
        ''' </summary>
        ''' ----------------------------------------------------------------------------------------------------
        Private WithEvents DebuggerCheckTimer As Timer

        ''' <summary>
        ''' The interval, in milliseconds, to check for the presence of a debugger attached to the current process.
        ''' </summary>
        Protected checkInterval As Integer = 1000 ' ms

        ''' ----------------------------------------------------------------------------------------------------
        ''' <summary>
        ''' Flag to keep track of the last result from a call to <see cref="NativeMethods.IsDebuggerPresent()"/>
        ''' </summary>
        ''' ----------------------------------------------------------------------------------------------------
        Protected lastIsDebuggerPresent As Boolean

#End Region

#Region " Events "

        ''' ----------------------------------------------------------------------------------------------------
        ''' <summary>
        ''' Occurs when a debugger is attached to or detached from the current process.
        ''' </summary>
        ''' ----------------------------------------------------------------------------------------------------
        Public Event StatusChanged As EventHandler(Of DebuggerNotifyEventArgs)

#End Region

#Region " Constructors "

        ''' ----------------------------------------------------------------------------------------------------
        ''' <summary>
        ''' Initializes a new instance of the <see cref="DebuggerNotify"/> class.
        ''' </summary>
        ''' ----------------------------------------------------------------------------------------------------
        <DebuggerNonUserCode>
        Public Sub New()

            Me.DebuggerCheckTimer = New Timer(Me.checkInterval) With {
                .AutoReset = True
            }

            Me.lastIsDebuggerPresent = NativeMethods.IsDebuggerPresent()
            Me.DebuggerCheckTimer.Start()

        End Sub

#End Region

#Region " Event Invocators "

        ''' ----------------------------------------------------------------------------------------------------
        ''' <summary>
        ''' Raises the <see cref="DebuggerNotify.StatusChanged"/> event.
        ''' </summary>
        ''' ----------------------------------------------------------------------------------------------------
        ''' <param name="e">
        ''' The <see cref="DebuggerNotifyEventArgs"/> instance containing the event data.
        ''' </param>
        ''' ----------------------------------------------------------------------------------------------------
        <DebuggerStepThrough>
        Protected Overridable Sub OnStatusChanged(ByVal e As DebuggerNotifyEventArgs)
            If (Me.StatusChangedEvent IsNot Nothing) Then
                RaiseEvent StatusChanged(Me, e)
            End If
        End Sub

#End Region

#Region " Event Handlers "

        ''' ----------------------------------------------------------------------------------------------------
        ''' <summary>
        ''' Handles the <see cref="Timer.Elapsed"/> event of the <see cref="DebuggerNotify.DebuggerCheckTimer"/> object.
        ''' </summary>
        ''' ----------------------------------------------------------------------------------------------------
        ''' <param name="sender">
        ''' The source of the event.
        ''' </param>
        '''
        ''' <param name="e">
        ''' The <see cref="ElapsedEventArgs"/> instance containing the event data.
        ''' </param>
        ''' ----------------------------------------------------------------------------------------------------
        Private Sub DebuggerCheckTimer_Elapsed(sender As Object, e As ElapsedEventArgs) Handles DebuggerCheckTimer.Elapsed

            Dim isDebuggerPresent As Boolean = NativeMethods.IsDebuggerPresent()
            If (isDebuggerPresent <> Me.lastIsDebuggerPresent) Then
                Me.lastIsDebuggerPresent = isDebuggerPresent
                Me.OnStatusChanged(New DebuggerNotifyEventArgs(isDebuggerPresent))
            End If

        End Sub

#End Region

#Region " IDisposable Implementation "

        ''' ----------------------------------------------------------------------------------------------------
        ''' <summary>
        ''' Flag to detect redundant calls.
        ''' </summary>
        ''' ----------------------------------------------------------------------------------------------------
        Private disposedValue As Boolean

        ''' ----------------------------------------------------------------------------------------------------
        ''' <summary>
        ''' Releases all the resources used by this instance.
        ''' </summary>
        ''' ----------------------------------------------------------------------------------------------------
        ''' <param name="disposing">
        ''' <see langword="True"/> to release both managed and unmanaged resources;
        ''' <see langword="False"/> to release only unmanaged resources.
        ''' </param>
        ''' ----------------------------------------------------------------------------------------------------
        Protected Overridable Sub Dispose(disposing As Boolean)
            If Not (Me.disposedValue) AndAlso (disposing) Then
                Me.DebuggerCheckTimer?.Dispose()
            End If
            Me.disposedValue = True
        End Sub

        ''' ----------------------------------------------------------------------------------------------------
        ''' <summary>
        ''' Releases all the resources used by this instance.
        ''' </summary>
        ''' ----------------------------------------------------------------------------------------------------
        Public Sub Dispose() Implements IDisposable.Dispose
            Me.Dispose(True)
        End Sub

#End Region

    End Class

End Namespace

#End Region


DebuggerNotifyEventArgs.vb
Código (vbnet) [Seleccionar]
#Region " Imports "

Imports System

#End Region

#Region " DebuggerNotifyEventArgs "

Namespace DevCase.Core.Diagnostics.Debug

   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' Provides the event data for the <see cref="DebuggerNotify.StatusChanged"/> event.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   Public NotInheritable Class DebuggerNotifyEventArgs : Inherits EventArgs

#Region " Constructors "

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets a value indicating whether a debugger in user-mode is attached to the current process.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Public ReadOnly Property IsAttached As Boolean

#End Region

#Region " Constructors "

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Prevents a default instance of the <see cref="DebuggerNotifyEventArgs"/> class from being created.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Private Sub New()
       End Sub

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Initializes a new instance of the <see cref="DebuggerNotifyEventArgs"/> class.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <param name="isAttached">
       ''' A value indicating whether a debugger in user-mode is attached to the current process.
       ''' </param>
       ''' ----------------------------------------------------------------------------------------------------
       Public Sub New(ByVal isAttached As Boolean)
           Me.IsAttached = isAttached
       End Sub

#End Region

   End Class

End Namespace

#End Region


PreventDebuggerContext.vb
Código (vbnet) [Seleccionar]
#Region " Imports "

Imports System

#End Region

#Region " Usage Examples "

' Using preventDebugger As New PreventDebuggerContext()
'     ' Insert your non-debuggable task here...
'     Do While True
'         Thread.Sleep(1000)
'     Loop
' End Using

#End Region

#Region " PreventDebuggerContext "

Namespace DevCase.Core.Diagnostics.Debug

   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' Prevents a debugger in user-mode from being attached to the current process,
   ''' and immediately terminates the current process after writing a message to the Windows Application event log.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   ''' <example> This is a code example.
   ''' <code>
   ''' Using preventDebugger As New PreventDebuggerContext()
   '''     ' Insert your non-debuggable task here...
   '''     Do While True
   '''         Thread.Sleep(1000)
   '''     Loop
   ''' End Using
   ''' </code>
   ''' </example>
   ''' ----------------------------------------------------------------------------------------------------
   Public NotInheritable Class PreventDebuggerContext : Implements IDisposable

#Region " Private Fields "

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' The <see cref="DevCase.Core.Diagnostics.Debug.DebuggerNotify"/> instance.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Private WithEvents DebuggerNotify As DebuggerNotify

#End Region

#Region " Constructors "

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Initializes a new instance of the <see cref="PreventDebuggerContext"/> class.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Public Sub New()
           Me.DebuggerNotify = New DebuggerNotify()
       End Sub

#End Region

#Region " Event Handlers "

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Handles the <see cref="DevCase.Core.Diagnostics.Debug.DebuggerNotify.StatusChanged"/> event of the <see cref="PreventDebuggerContext.DebuggerNotify"/> object.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <param name="sender">
       ''' The source of the event.
       ''' </param>
       '''
       ''' <param name="e">
       ''' The <see cref="DebuggerNotifyEventArgs"/> instance containing the event data.
       ''' </param>
       ''' ----------------------------------------------------------------------------------------------------
       Private Sub DebuggerNotify_StatusChanged(ByVal sender As Object, ByVal e As DebuggerNotifyEventArgs) Handles DebuggerNotify.StatusChanged

           If (e.IsAttached) Then
               Environment.FailFast("A debugger was attached to the current process.")
           End If

       End Sub

#End Region

#Region " IDisposable Implementation "

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Flag to detect redundant calls.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Private disposedValue As Boolean

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Releases all the resources used by this instance.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <param name="disposing">
       ''' <see langword="True"/> to release both managed and unmanaged resources;
       ''' <see langword="False"/> to release only unmanaged resources.
       ''' </param>
       ''' ----------------------------------------------------------------------------------------------------
       Private Sub Dispose(disposing As Boolean)
           If Not (Me.disposedValue) AndAlso (disposing) Then
               Me.DebuggerNotify?.Dispose()
           End If
           Me.disposedValue = True
       End Sub

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Releases all the resources used by this instance.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Public Sub Dispose() Implements IDisposable.Dispose
           Me.Dispose(True)
       End Sub

#End Region

   End Class

End Namespace

#End Region





Modo de empleo de la clase PreventDebuggerContext:
Código (vbnet) [Seleccionar]
Using preventDebugger As New PreventDebuggerContext()

   ' Insert your non-debuggable task here...
   Do While True
       Thread.Sleep(1000)
   Loop

End Using


O simplemente creando una nueva instancia que tenga efecto durante todo el tiempo de vida de la aplicación:
Código (vbnet) [Seleccionar]
Friend Shared ReadOnly PreventDebugger As New PreventDebuggerContext()

Modo de empleo de la clase DebuggerNotify:
Código (vbnet) [Seleccionar]
Public Class Form1

   Private WithEvents DebuggerNotify As DebuggerNotify

    Public Sub New()
        MyClass.InitializeComponent()
        Me.DebuggerNotify = New DebuggerNotify()
    End Sub

   Private Sub DebuggerNotify_StatusChanged(ByVal sender As Object, ByVal e As DebuggerNotifyEventArgs) Handles DebuggerNotify.StatusChanged
       Dim msg As String = $"Debugger status changed to {NameOf(e.IsAttached)}: {e.IsAttached}"
       Console.WriteLine(msg)
   End Sub

End Class


PD: intenta darle créditos a la librería DevCase for .NET Framework si esto lo publicas por ahí...

Saludos.








**Aincrad**

Gracias. Funciona perfecto.  ;-)