Advertisement
waliedassar

ZwClose As Anti-Debug Trick

Feb 9th, 2013
1,062
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.78 KB | None | 0 0
  1. //http://waleedassar.blogspot.com
  2. //http://www.twitter.com/waleedassar
  3.  
  4. ZwClose(Invalid or protected handle); has been used as an effective anti-debug trick since
  5. in the presence of a debugger, an exception of type 0xC0000008 (STATUS_INVALID_HANDLE) or
  6. 0xC0000235 (STATUS_HANDLE_NOT_CLOSABLE) is raised and then the installed exception handler
  7. will detect the state of being under a debugger. On the other hand, if no debugger is present,
  8. the function simply return 0xC0000008 (STATUS_INVALID_HANDLE) or 0xC0000235.
  9.  
  10. There is a risk using this function as anti-debug, which is randomly choosing a value that is
  11. already a valid handle value. To bypass this risk, we have to understand the inner working of
  12. the "NtCloseHandle" function in kernel-mode.
  13.  
  14. 1) Don't use zero since NtClose in this case will not raise any exceptions.
  15. See. the "nt!ObpCloseHandle" function.
  16. 2) Don't use -1 or -2 since both values are reserved for GetCurrentProcess() and
  17. GetCurrentThread() and NtClose in this case will not raise any exceptions.
  18.  See the "nt!ObpCloseHandle" function.
  19.  
  20. fffff800`035888b2 4885db        test    rbx,rbx
  21. fffff800`035888b5 0f848d000000  je      nt! ?? ::NNGAKEGL::`string'+0x34fec (fffff800`03588948)
  22.  
  23. nt! ?? ::NNGAKEGL::`string'+0x34f5b:
  24. fffff800`035888bb 4883fbfe      cmp     rbx,0FFFFFFFFFFFFFFFEh
  25. fffff800`035888bf 0f8483000000  je      nt! ?? ::NNGAKEGL::`string'+0x34fec (fffff800`03588948)
  26.  
  27. nt! ?? ::NNGAKEGL::`string'+0x34f65:
  28. fffff800`035888c5 4883fbff      cmp     rbx,0FFFFFFFFFFFFFFFFh
  29. fffff800`035888c9 747d          je      nt! ?? ::NNGAKEGL::`string'+0x34fec (fffff800`03588948)
  30.  
  31. nt! ?? ::NNGAKEGL::`string'+0x34fec:
  32. fffff800`03588948 b8080000c0    mov     eax,0C0000008h
  33. fffff800`0358894d e942270400    jmp     nt!ObpCloseHandle+0x94 (fffff800`035cb094)
  34.  
  35.  
  36. 3) To be very sure that the handle value is invalid, unset all the bits of 0x3FC.
  37. In other word, invalid_handle=random_value ^ 0x3FC;
  38. See the "ExMapHandleToPointer" function.
  39.  
  40. nt!ExMapHandleToPointer:
  41. fffff800`035cb0d0 4883ec28      sub     rsp,28h
  42. fffff800`035cb0d4 f7c2fc030000  test    edx,3FCh
  43. fffff800`035cb0da 747c          je      nt!ExMapHandleToPointer+0x88 (fffff800`035cb158)
  44.  
  45.  
  46. OR
  47. Make the value look like a kernel handle by setting the most significant bit(s) of the value
  48. by ORing with 0x80000000 (32-Bit system) or ORing with 0xFFFFFFFF80000000 (64-bit system).
  49.  
  50. One famous method of bypassing this trick is intercepting the call and changing the parameter
  51. of the stack to a valid value or even changing the system call number to something like
  52. ZwFlushKey such that no exceptions are raised.
  53.  
  54. So, to enhance the trick, make sure that the return value of the calls
  55. is 0xC0000008 or 0x0xC0000235. Also, make sure to check the dead stack i.e. dword ptr[esp-4]
  56. for the invalid value you supplied.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement