Académique Documents
Professionnel Documents
Culture Documents
Home Dev Blog Anti Debugging Protection Techniques With Examples
Let's talk
Dev Blog
Categories
Cybersecurity
Anti Debugging Protection T
Virtualization
With Examples
Blockchain
In terms of software, reverse engineering is the process
AI and Machine Learning to obtain closed information about how it works and wh
While software reversing can be used for legal purpose
C++ tips
analysis or undocumented system research, it's general
Driver development by hackers for illegal activities.
System development for
Apriorit Research and Reversing team decided to share
Windows
experience and provide a list of popular simple and adv
Development for Linux use to protect your software from illegal reversing. And
Development for Mac hackers, they use this opportunity to flex their muscle a
experienced reverser can bypass these protections (inclu
Mobile development
samples). Send us a message
https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software 1/36
6/5/2019 Anti Debugging Protection Techniques With Examples
Web Development Our reversers note less effective and more effective pro
Reverse engineering
some
R&D Services insights about
Specialties choosing your
Competences own set.
About Us Blog
QA and testing
Written by:
White Papers Let's talk
Oleg Kulchytskyy,
Software Architect
Top content
Anton Kukoba,
Security Research Leader
IsDebuggerPresent
TLS Callback
Windows File System Filter
Driver Development Tutorial
NtGlobalFlag
This tutorial provides you
with easy to understand
steps for a simple file system Heap Flags and ForceFlags
filter driver development The
CheckRemoteDebuggerPresent and NtQueryInformatio
Debugging messages
Send us a message
https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software 2/36
6/5/2019 Anti Debugging Protection Techniques With Examples
Windows Process Monitoring
and Management Tips Conclusion
R&D Services Specialties Competences About Us Blog
The following article will help
you to understand principles References
of Windows processes
starting In addition it will
Let's talk
Related services:
Reverse Engineering
IsDebuggerPresent
int main()
{
if (IsDebuggerPresent())
{
std::cout << "Stop debugging program!" << std::endl;
exit(-1);
}
return 0;
}
0:000< u kernelbase!IsDebuggerPresent L3
KERNELBASE!IsDebuggerPresent:
751ca8d0 64a130000000 mov eax,dword ptr fs:[00000030h]
751ca8d6 0fb64002 movzx eax,byte ptr [eax+2]
751ca8da c3 ret
0:000< u kernelbase!IsDebuggerPresent L3
KERNELBASE!IsDebuggerPresent:
00007ffc`ab6c1aa0 65488b042560000000 mov rax,qword ptr gs:[60
00007ffc`ab6c1aa9 0fb64002 movzx eax,byte ptr [rax+2]
00007ffc`ab6c1aad c3 Send us a message
ret
https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software 4/36
6/5/2019 Anti Debugging Protection Techniques With Examples
R&D Services
WeseeSpecialties Competences
the PEB (Process About
Environment Us structure
Block) Blog b
to the fs segment (the 60h offset relative to the gs seg
we look by the 2 offset in the PEB, we’ll find the BeingD
Let's talk
0:000< dt _PEB
ntdll!_PEB
+0x000 InheritedAddressSpace : UChar
+0x001 ReadImageFileExecOptions : UChar
+0x002 BeingDebugged : UChar
WORD GetVersionWord()
{
OSVERSIONINFO verInfo = { sizeof(OSVERSIONINFO) };
GetVersionEx(&verInfo);
return MAKEWORD(verInfo.dwMinorVersion, verInfo.dwMajorVers
}
BOOL IsWin8OrHigher() { return GetVersionWord() >= _WIN32_WINNT
BOOL IsVistaOrHigher() { return GetVersionWord() >= _WIN32_WINN
TLS Callback
NtGlobalFlag
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Ma
FLG_HEAP_ENABLE_TAIL_CHECK (0x10)
FLG_HEAP_ENABLE_FREE_CHECK (0x20)
FLG_HEAP_VALIDATE_PARAMETERS (0x40)
Send us a message
https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software 7/36
6/5/2019 Anti Debugging Protection Techniques With Examples
Send us a message
https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software 8/36
6/5/2019 Anti Debugging Protection Techniques With Examples
https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software 9/36
6/5/2019 Anti Debugging Protection Techniques With Examples
exit(-1);
}
R&D Services}void
Specialties Competences
CheckGlobalFlagsClearInFile()
About Us Blog
{
HANDLE hExecutable = INVALID_HANDLE_VALUE;
HANDLE hExecutableMapping = NULL;
PBYTE pMappedImageBase = NULL;
__try
{
Let's talk
PBYTE pImageBase = (PBYTE)GetModuleHandle(NULL);
PIMAGE_SECTION_HEADER pImageSectionHeader = FindRDataSe
TCHAR pszExecutablePath[MAX_PATH];
DWORD dwPathLength = GetModuleFileName(NULL, pszExecuta
if (0 == dwPathLength) __leave;
hExecutable = CreateFile(pszExecutablePath, GENERIC_REA
OPEN_EXISTING, 0, NULL);
if (INVALID_HANDLE_VALUE == hExecutable) __leave;
hExecutableMapping = CreateFileMapping(hExecutable, NUL
NULL);
if (NULL == hExecutableMapping) __leave;
pMappedImageBase = (PBYTE)MapViewOfFile(hExecutableMapp
pImageSectionHeader->PointerToRawData + pImageSecti
if (NULL == pMappedImageBase) __leave;
PIMAGE_NT_HEADERS pImageNtHeaders = GetImageNtHeaders(p
PIMAGE_LOAD_CONFIG_DIRECTORY pImageLoadConfigDirectory
(PIMAGE_LOAD_CONFIG_DIRECTORY)(pMappedImageBase
+ (pImageSectionHeader->PointerToRawData
+ (pImageNtHeaders-
>OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
pImageSectionHeader->VirtualAddress)));
if (pImageLoadConfigDirectory->GlobalFlagsClear != 0)
{
std::cout << "Stop debugging program!" << std::endl
exit(-1);
}
}
__finally
{
if (NULL != pMappedImageBase)
UnmapViewOfFile(pMappedImageBase);
if (NULL != hExecutableMapping)
CloseHandle(hExecutableMapping);
if (INVALID_HANDLE_VALUE != hExecutable)
CloseHandle(hExecutable);
}
}
+0x044 ForceFlags : 0x40000060
Let's talk
For x64:
0:000> uf kernelbase!CheckRemotedebuggerPresent
KERNELBASE!CheckRemoteDebuggerPresent:
...
75207a24 6a00 push 0
75207a26 6a04 push 4
75207a28 8d45fc Sendlea
us a message
eax,[ebp-4]
https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software 13/36
6/5/2019 Anti Debugging Protection Techniques With Examples
75207a2b 50 push eax
75207a2c 6a07 push 7
75207a2e ff7508 push dword ptr [ebp+8]
R&D Services75207a31
Specialties
ff151c602775
Competences
call
About Us Blog
dword ptr [KERNELBASE!_imp__Nt
(7527601c)]
75207a37 85c0 test eax,eax
75207a39 0f88607e0100 js KERNELBASE!CheckRemoteDebugger
...
Let's talk
If we take a look at the NtQueryInformationProcess doc
Assembler listing will show us that the CheckRemoteDeb
assigned the DebugPort value, as the ProcessInformat
(the second one) is 7. The following anti-debugging code
calling the NtQueryInformationProcess:
if (NULL != hNtDll)
{
NtQueryInformationProcess = (pfnNtQueryInformationProce
"NtQueryInformationProcess");
if (NULL != NtQueryInformationProcess)
{
status = NtQueryInformationProcess(
GetCurrentProcess(),
ProcessDebugPort,
&isDebuggerPresent,
sizeof(DWORD),
NULL);
if (status == 0x00000000 && isDebuggerPresent != 0)
{
std::cout << "Stop debugging program!" << std::
exit(-1);
}
}
}
return 0;
}
https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software 15/36
6/5/2019 Anti Debugging Protection Techniques With Examples
}
break;
R&D Services }return
Specialties
TRUE;
Competences About Us Blog
}
ProcessDebugObjectHandle
status = NtQueryInformationProcess(
GetCurrentProcess(),
ProcessDebugObjectHandle,
&hProcessDebugObject,
sizeof(HANDLE),
NULL);
if (0x00000000 == status && NULL != hProcessDebugObject)
{
std::cout << "Stop debugging program!" << std::endl;
exit(-1);
}
ProcessDebugFlags
Send us a message
https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software 16/36
6/5/2019 Anti Debugging Protection Techniques With Examples
status = NtQueryInformationProcess(
GetCurrentProcess(),
ProcessDebugObjectHandle,
&debugFlags,
Let's talk
sizeof(ULONG),
NULL);
if (0x00000000 == status && NULL != debugFlags)
{
std::cout << "Stop debugging program!" << std::endl;
exit(-1);
}
ProcessBasicInformation
https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software 17/36
6/5/2019 Anti Debugging Protection Techniques With Examples
return processName;
}
do
R&D Services {
Specialties Competences About Us Blog
if (pe32.th32ProcessID == pid)
{
processName = pe32.szExeFile;
break;
} Let's talk
} while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return processName;
}
status = NtQueryInformationProcess(
GetCurrentProcess(),
ProcessBasicInformation,
&processBasicInformation,
sizeof(PROCESS_BASIC_INFORMATION),
NULL);
std::wstring parentProcessName =
GetProcessNameById((DWORD)processBasicInformation.InheritedFrom
if (L"devenv.exe" == parentProcessName)
{
std::cout << "Stop debugging program!" << std::endl;
exit(-1);
}
1. Set ProcessDebugObjectHandle to 0
2. Set ProcessDebugFlags to 1
3. For ProcessBasicInformation, change the Inheri
value to the ID of another process, e.g. explorer.exe
Breakpoints
1. Software breakpoints
2. Hardware breakpoints
DebuggeeFunction:
013C16DB jmp DebuggeeFunction (013C4950h)
Send us a message
https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software 19/36
6/5/2019 Anti Debugging Protection Techniques With Examples
Hardware Breakpoints
https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software 20/36
6/5/2019 Anti Debugging Protection Techniques With Examples
{
std::cout << "Stop debugging program!" << std::endl;
exit(-1);
R&D Services }Specialties Competences About Us Blog
}
0:000> u KERNELBASE!GetThreadContext L6
KERNELBASE!GetThreadContext:
7538d580 8bff mov edi,edi
7538d582 55 push ebp
7538d583 8bec mov ebp,esp
7538d585 ff750c push dword ptr [ebp+0Ch]
7538d588 ff7508 push dword ptr [ebp+8]
7538d58b ff1504683975 call dword ptr [KERNELBASE!_imp__Nt
(75396804)]
0:000> dt ntdll!_EXCEPTION_REGISTRATION_RECORD
+0x000 Next : Ptr32 _EXCEPTION_REGISTRATION_RECO
+0x004 Handler : Ptr32 _EXCEPTION_DISPOSITION
Send us a message
https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software 22/36
6/5/2019 Anti Debugging Protection Techniques With Examples
0:000> !exchain
00a5f3bc: AntiDebug!_except_handler4+0 (008b7530)
CRT scope 0, filter: AntiDebug!SehInternals+67 (00883d67)
func: AntiDebug!SehInternals+6d (00883d6d)
00a5f814: AntiDebug!__scrt_stub_for_is_c_termination_complete+1
00a5f87c: AntiDebug!_except_handler4+0 (008b7530)
CRT scope 0, filter: AntiDebug!__scrt_common_main_seh+1b0 (0
func: AntiDebug!__scrt_common_main_seh+1cb (0
00a5f8e8: ntdll!_except_handler4+0 (775674a0)
CRT scope 0, filter: ntdll!__RtlUserThreadStart+54386 (7757f
func: ntdll!__RtlUserThreadStart+543cd (7757f
00a5f900: ntdll!FinalExceptionHandlerPad4+0 (77510213)
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion
0:000> kn
# ChildEBP RetAddr
00 0059f06c 775100b1 AntiDebug!ExceptionRoutine
01 0059f090 77510083 ntdll!ExecuteHandler2+0x26
02 0059f158 775107ff ntdll!ExecuteHandler+0x24
03 0059f158 003b11a5 ntdll!KiUserExceptionDispatcher+0xf
04 0059fa90 003d7f4e AntiDebug!main+0xb5
05 0059faa4 003d7d9a AntiDebug!invoke_main+0x1e
06 0059fafc 003d7c2d AntiDebug!__scrt_common_main_seh+0x15a
07 0059fb04 003d7f68 AntiDebug!__scrt_common_main+0xd
08 0059fb0c 753e7c04 AntiDebug!mainCRTStartup+0x8
09 0059fb20 7752ad1f KERNEL32!BaseThreadInitThunk+0x24
0a 0059fb68 7752acea ntdll!__RtlUserThreadStart+0x2f
0b 0059fb78 00000000 ntdll!_RtlUserThreadStart+0x1b
0:000> u ntdll!ExecuteHandler2+24 L3
ntdll!ExecuteHandler2+0x24:
775100af ffd1 call ecx
775100b1 648b2500000000 mov esp,dword ptr fs:[0]
775100b8 648f0500000000 pop dword ptr fs:[0]
0:000> bp 775100af
Send us a message
https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software 26/36
6/5/2019 Anti Debugging Protection Techniques With Examples
Let’s take a look at the call stack that led to the VEH ha
0:000> kn
# ChildEBP RetAddr
00 001cf21c 774d6822 AntiDebug!ExceptionHandler
01 001cf26c 7753d151 ntdll!RtlpCallVectoredHandlers+0xba
02 001cf304 775107ff ntdll!RtlDispatchException+0x72
03 001cf304 00bf4a69 ntdll!KiUserExceptionDispatcher+0xf
04 001cfc1c 00c2680e AntiDebug!main+0x59
05 001cfc30 00c2665a AntiDebug!invoke_main+0x1e
06 001cfc88 00c264ed AntiDebug!__scrt_common_main_seh+0x15a
07 001cfc90 00c26828 AntiDebug!__scrt_common_main+0xd
08 001cfc98 753e7c04 AntiDebug!mainCRTStartup+0x8
09 001cfcac 7752ad1f KERNEL32!BaseThreadInitThunk+0x24
0a 001cfcf4 7752acea ntdll!__RtlUserThreadStart+0x2f
0b 001cfd04 00000000 ntdll!_RtlUserThreadStart+0x1b
0:000> u main+59 L1
AntiDebug!main+0x59
00bf4a69 cd02 int 1
Send us a message
https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software 27/36
6/5/2019 Anti Debugging Protection Techniques With Examples
NtCreateThreadEx
How to bypass NtCreateThreadEx Let's talk
Handle Tracing
EXCEPTION_DISPOSITION ExceptionRoutine(
PEXCEPTION_RECORD ExceptionRecord,
PVOID EstablisherFrame,
PCONTEXT ContextRecord,
PVOID DispatcherContext)
{
if (EXCEPTION_INVALID_HANDLE == ExceptionRecord->ExceptionC
{
std::cout << "Stop debugging program!" << std::endl;
exit(-1);
}
return ExceptionContinueExecution;
}
int main()
{
__asm
{
// set SEH handler
push ExceptionRoutine
push dword ptr fs : [0]
mov dword ptr fs : [0], esp
}
CloseHandle((HANDLE)0xBAAD);
__asm
{
// return original SEH handler
mov eax, [esp]
mov dword ptr fs : [0], eax
add esp, 8
}
return 0
}
Send us a message
https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software 31/36
6/5/2019 Anti Debugging Protection Techniques With Examples
Stack
R&D Services
Segment
Specialties Manipulation
Competences About Us Blog
Read also:
How to Reverse Engineer Software (Windows)
Way
Debugging messages
| Conclusion
This article has described a series of anti-reverse engin
particular anti-debugging methods, starting with the sim
ways to bypass them. This is just a limited list, as there
technologies and approaches that you can continue inve
1. Self-debugging process
2. Debugger detection using the FindWindow function
3. Time calculation approach (see this article)
4. NtQueryObject
5. BlockInput
6. NtSetDebugFilterState
7. Self-modifying code
User Rating: 5 / 5
Send us a message
https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software 34/36
6/5/2019 Anti Debugging Protection Techniques With Examples
Let's talk
Let's talk
Have a Project? Book an Explorat
Send Apriorit a request for proposal! We’ll get back to you with Do not have any specific task for us in m
details and estimations. interesting? Get a quick Apriorit intro to
capabilities.
Email Phone
Contact Us
P: +1 202-780-9
Subject of your request E: info@apriorit
Send us a message
https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software 35/36
6/5/2019 Anti Debugging Protection Techniques With Examples
Let's talk
© 2004-2019 Apriorit. Privacy Policy Terms and Conditions of Use
Send us a message
https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software 36/36