user24684540
user24684540

Reputation: 33

NtTerminateThread is returning STATUS_INVALID_HANDLE when terminating self

Hello I am trying to terminate the current thread using NtTerminateThread. I know that the function for the syscall takes 2 arguments which are the thread handle and the exit status but whenever I try to exit the current thread it gives me STATUS_INVALID_HANDLE. Im getting the handle from the function GetCurrentThread which returns 0xfffffffffffffffe.

Im trying to exit with a status of STATUS_SUCCESS which is 0x00000000.

RAX return value showing STATUS_INVALID_HANDLE RAX return value showing STATUS_INVALID_HANDLE

ASM:

mov rcx, 0xfffffffffffffffe
mov rdx, 0x0
mov eax, 0x53
syscall

Upvotes: 0

Views: 105

Answers (2)

David Wohlferd
David Wohlferd

Reputation: 7528

Your asm code is calling SYSCALL directly. This is unsupported under Windows. Not only can they move things around, but they do move things around. A direct syscall that works today may not tomorrow or may fail on someone else's computer.

That said, looking at the code for NtTerminateThread (on my machine):

00007FFBF5910C20  mov         r10,rcx  
00007FFBF5910C23  mov         eax,53h  
00007FFBF5910C28  test        byte ptr [7FFE0308h],1  
00007FFBF5910C30  jne         00007FFBF5910C35  
00007FFBF5910C32  syscall  
00007FFBF5910C34  ret  

So rather than putting the handle in rcx, it goes in r10. And while there is indeed a function named NtCurrentThread, on my machine it's returning the same value as GetCurrentThread (ie 0xfffffffffffffffe).

No, I don't know what's stored at 0x7FFE0308. That's one of the downsides of calling unsupported code. On my machine it was 0. Had the jump been taken, it would have done int 0x2E, which sounds bad.

In conclusion: Call the NtTerminateThread function rather than trying to work around it. It works the way you expect, and is more likely to keep working tomorrow.

Upvotes: 0

3CxEZiVlQ
3CxEZiVlQ

Reputation: 38773

NtTerminateThread manual: ThreadHandle ... or the NtCurrentThread pseudo-handle If this value is NULL, the calling thread is terminated.

That's all what you need

NtTerminateThread(NULL, STATUS_SUCCESS);

Or

NtTerminateThread(NtCurrentThread(), STATUS_SUCCESS);

GetCurrentThread() is not what the function expected.

Upvotes: 2

Related Questions