反调试器技术:如何使用VB.NET从调试器中隐藏线程?

时间:2019-07-19 19:27:50

标签: c++ vb.net debugging reverse-engineering translate

几天来,我一直在尝试记录自己有关反调试器技术的信息。

因此,我发现了许多不同的方法来实现这一目标。在这些技术中,由于使用了NtSetInformationThread方法,我发现可以从调试器中隐藏线程。 我的项目是在用VB.NET编写的代码中使用此方法。

以下是我在研究中发现的技术的描述,我发现它得到了很好的解释:

  

在Windows 2000中,一类新的线程信息传输到   出现NtSetInformationThread函数– ThreadHideFromDebugger。   这是由以下人员提供的首批反调试技术之一   Windows在Microsoft寻找如何防止反向工程,   它非常强大。如果为线程设置了此标志,则该   线程停止发送有关调试事件的通知

     

From this website

因此,我找到了一个来自此site的资源来实现这一目标。 这是他在C ++中使用的方法:

typedef enum _THREADINFOCLASS {

    ThreadHideFromDebugger=17

} THREADINFOCLASS;

extern "C" ULONG __stdcall NtSetInformationThread(
    __in HANDLE ThreadHandle,
    __in THREADINFOCLASS ThreadInformationClass,
    __in_bcount(ThreadInformationLength) PVOID ThreadInformation,
    __in ULONG ThreadInformationLength
);

ULONG main()
{
    ULONG Status;

    Status=NtSetInformationThread(GetCurrentThread(), ThreadHideFromDebugger, NULL, 0);

    if(Status)
        printf("Error with NtSetInformationThread : 0x%xn", Status);

    __asm {int 3}
    return 0; 
}

因此,我尝试使用C ++的初学者知识来翻译此代码(老实说,我对这种语言了解不多)。 这是它给的:

Private Declare Function NtSetInformationThread Lib "Ntdll.dll" (ByVal hThread As Long, ByVal ThreadInformationClass As Long, ByVal ThreadInformation As Long, ByVal ThreadInformationLength As Long) As Long
<DllImport("kernel32.dll")>

Public Shared Function GetCurrentThreadId() As UInteger
End Function

Shared Function HideFromDebugger() As UInteger
    Dim Status As UInteger

    Status = NtSetInformationThread(GetCurrentThreadId(), 17, Nothing, 0)

    If Status <> 0 Then

        Console.Write("Error with NtSetInformationThread : 0x{0:x}n", Status)
        Debugger.Break()
        Return 0
    End If
End Function

但是,我觉得我在某个地方错了。例如,我不明白参数“ 17”的含义。你能告诉我我走的路是否正确吗?

每个答案对我来说都是非常有价值的:)

1 个答案:

答案 0 :(得分:1)

您快到了,但是您当前的代码有两个问题:

首先,您对NtSetInformationThread函数的P / Invoke声明不太正确,我建议您坚持使用DllImport,因为您在互联网上找到的大多数Declare Function声明都是写的用于VB6,并且与VB.NET不兼容。

这是更正的版本:

<DllImport("Ntdll.dll")>
Public Shared Function NtSetInformationThread(ByVal hThread As IntPtr, ByVal ThreadInformationClass As Integer, ByVal ThreadInformation As IntPtr, ByVal ThreadInformationLength As UInteger) As UInteger
End Function

第二,请注意C ++代码如何使用函数GetCurrentThread() not GetCurrentThreadId()。两者的不同之处在于,前者为您提供了一个句柄,而句柄更像是指向线程的指针,而后者仅为您提供了分配给该线程的数字ID。

您需要改用GetCurrentThread函数:

<DllImport("Kernel32.dll")>
Public Shared Function GetCurrentThread() As IntPtr
End Function
  

我不明白参数“ 17”是什么意思。

17ThreadHideFromDebugger的值,实际上没有任何特殊的来源或含义。它只是告诉NtSetInformationThread()要更改有关线程的哪些信息。