mirror of https://github.com/dahall/Vanara.git
Add two undocumented API in ntdll (#386)
API1: DbgUiSetThreadDebugObject API2: NtRemoveProcessDebugpull/387/head
parent
38e611f1e3
commit
a9ff5e3c8f
|
@ -300,6 +300,33 @@ namespace Vanara.PInvoke
|
||||||
[In] HPROCESS ParentProcess, [In] PROCESS_CREATE_FLAGS Flags, [In, Optional] IntPtr SectionHandle,
|
[In] HPROCESS ParentProcess, [In] PROCESS_CREATE_FLAGS Flags, [In, Optional] IntPtr SectionHandle,
|
||||||
[In, Optional] IntPtr DebugPort, [In, Optional] IntPtr ExceptionPort, uint JobMemberLevel);
|
[In, Optional] IntPtr DebugPort, [In, Optional] IntPtr ExceptionPort, uint JobMemberLevel);
|
||||||
|
|
||||||
|
/// <summary>Set the debug object handle in the TEB. This function is UNDOCUMENTED.</summary>
|
||||||
|
/// <param name="DebugObjectHandle">Debug object handle. Retrieve from NtQueryInformationProcess</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <para>The function returns an NTSTATUS success or error code.</para>
|
||||||
|
/// <para>
|
||||||
|
/// The forms and significance of NTSTATUS error codes are listed in the Ntstatus.h header file available in the DDK, and are
|
||||||
|
/// described in the DDK documentation under Kernel-Mode Driver Architecture / Design Guide / Driver Programming Techniques /
|
||||||
|
/// Logging Errors.
|
||||||
|
/// </para>
|
||||||
|
/// </returns>
|
||||||
|
[DllImport(Lib.NtDll, SetLastError = false, ExactSpelling = true)]
|
||||||
|
public static extern NTStatus DbgUiSetThreadDebugObject(IntPtr DebugObjectHandle);
|
||||||
|
|
||||||
|
/// <summary>Call the kernel to remove the debug object. This function is UNDOCUMENTED.</summary>
|
||||||
|
/// <param name="ProcessHandle">The process handle.</param>
|
||||||
|
/// <param name="DebugObjectHandle">Debug object handle. Retrieve from NtQueryInformationProcess</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <para>The function returns an NTSTATUS success or error code.</para>
|
||||||
|
/// <para>
|
||||||
|
/// The forms and significance of NTSTATUS error codes are listed in the Ntstatus.h header file available in the DDK, and are
|
||||||
|
/// described in the DDK documentation under Kernel-Mode Driver Architecture / Design Guide / Driver Programming Techniques /
|
||||||
|
/// Logging Errors.
|
||||||
|
/// </para>
|
||||||
|
/// </returns>
|
||||||
|
[DllImport(Lib.NtDll, SetLastError = false, ExactSpelling = true)]
|
||||||
|
public static extern NTStatus NtRemoveProcessDebug(HPROCESS ProcessHandle, IntPtr DebugObjectHandle);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>
|
/// <para>
|
||||||
/// [ <c>NtQueryInformationProcess</c> may be altered or unavailable in future versions of Windows. Applications should use the
|
/// [ <c>NtQueryInformationProcess</c> may be altered or unavailable in future versions of Windows. Applications should use the
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NUnit.Framework.Constraints;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
using Vanara.Extensions;
|
using Vanara.Extensions;
|
||||||
using Vanara.InteropServices;
|
|
||||||
using static Vanara.PInvoke.NtDll;
|
using static Vanara.PInvoke.NtDll;
|
||||||
|
|
||||||
namespace Vanara.PInvoke.Tests
|
namespace Vanara.PInvoke.Tests
|
||||||
|
@ -68,5 +64,65 @@ namespace Vanara.PInvoke.Tests
|
||||||
Assert.That(() => ppb = NtQueryInformationProcess<uint>(hProc, PROCESSINFOCLASS.ProcessPriorityBoost), Throws.Nothing);
|
Assert.That(() => ppb = NtQueryInformationProcess<uint>(hProc, PROCESSINFOCLASS.ProcessPriorityBoost), Throws.Nothing);
|
||||||
TestContext.WriteLine($"Priority boost: {ppb.Value}");
|
TestContext.WriteLine($"Priority boost: {ppb.Value}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void DbgUiSetThreadDebugObjectAndNtRemoveProcessDebugTest()
|
||||||
|
{
|
||||||
|
Kernel32.STARTUPINFO StartInfo = new Kernel32.STARTUPINFO
|
||||||
|
{
|
||||||
|
dwFlags = Kernel32.STARTF.STARTF_USESHOWWINDOW,
|
||||||
|
wShowWindow = (ushort)ShowWindowCommand.SW_HIDE
|
||||||
|
};
|
||||||
|
|
||||||
|
Assert.IsTrue(Kernel32.CreateProcess("notepad.exe", dwCreationFlags: Kernel32.CREATE_PROCESS.DEBUG_PROCESS | Kernel32.CREATE_PROCESS.CREATE_UNICODE_ENVIRONMENT, lpStartupInfo: StartInfo, lpProcessInformation: out Kernel32.SafePROCESS_INFORMATION Information));
|
||||||
|
|
||||||
|
using (Information)
|
||||||
|
using (NtQueryResult<IntPtr> DebugObjectHandleQueryResult = NtQueryInformationProcess<IntPtr>(Information.hProcess, PROCESSINFOCLASS.ProcessDebugObjectHandle))
|
||||||
|
{
|
||||||
|
Assert.That(DebugObjectHandleQueryResult, ResultIs.ValidHandle);
|
||||||
|
Assert.That(DebugObjectHandleQueryResult.Value, ResultIs.ValidHandle);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Assert.DoesNotThrow(() => DbgUiSetThreadDebugObject(DebugObjectHandleQueryResult.Value).ThrowIfFailed());
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Kernel32.SafeHPROCESS DebugProcessHandle = Kernel32.SafeHPROCESS.Null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
Assert.IsTrue(Kernel32.WaitForDebugEvent(out Kernel32.DEBUG_EVENT Event, Kernel32.INFINITE));
|
||||||
|
|
||||||
|
if (Event.dwDebugEventCode == Kernel32.DEBUG_EVENT_CODE.CREATE_PROCESS_DEBUG_EVENT)
|
||||||
|
{
|
||||||
|
DebugProcessHandle = new Kernel32.SafeHPROCESS(Event.u.CreateProcessInfo.hProcess);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.IsTrue(Kernel32.ContinueDebugEvent(Event.dwProcessId, Event.dwThreadId, Kernel32.DEBUG_CONTINUE.DBG_CONTINUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.AreNotEqual(Kernel32.SafeHPROCESS.Null, DebugProcessHandle);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DebugProcessHandle.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Assert.DoesNotThrow(() => DbgUiSetThreadDebugObject(IntPtr.Zero).ThrowIfFailed());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Assert.IsTrue(Kernel32.TerminateProcess(Information.hProcess, 0));
|
||||||
|
Assert.DoesNotThrow(() => NtRemoveProcessDebug(Information.hProcess, DebugObjectHandleQueryResult.Value).ThrowIfFailed());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue