|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionIn recent times, tools for use in reverse engineering have flourished. There are plenty of resource sites for those who are interested in the field, and the field is very much worth the time invested in it. I found that learning C++ while introducing myself to reverse engineering and assembly language really helped me to understand how code works, and improved my C/C++ coding and my ASM coding at the same time. However, reverse engineering also has a darker side. Crackers are individuals who use their knowledge of reverse engineering to reverse another programmer's code, often to decode how a serial is processed or to remove a protection from a trial. Naturally, a pioneer will want to protect their investment; this can be done with tools such as Themida, Execryptor, Armadillo, and even a protection system coded by a CodeProject resident Jim Charles named Eagle Protector. This article is meant to inform individuals of some anti-debugging techniques, and is not meant to be all-inclusive, nor does it explore some of the more complex routines that commercial protectors use. BackgroundAn individual reading this should have a solid understanding of ASM, how computers handle memory, the Win32 Debugging API, and at least some knowledge of Windows internals. This code most likely will not work on any *nix platform due to the fundamental differences of the Operating Systems. Any other knowledge in the field of reverse engineering is also a plus. One great thing about learning and implementing anti-debugging is that you also develop your reversing skills, which is a great plus to anyone interested in the field. Along with the other mentioned subjects, an interested reader should also be familiar with the tools used for binary application reversing such as OllyDBG, WinDBG, SoftICE, IDA Pro, and others. Here are some links to some information that is important for readers to be familiar with before reading the following text: IsDebuggerPresentThis is probably the simplest method for debugger protection. This function is part of the Win32 Debugging API, and its reference page can be found here: MSDN. if(IsDebuggerPresent())
{
MessageBox(NULL, TEXT("Please close your debugging application" +
" and restart the program"),
TEXT("Debugger Found!"), 0);
ExitProcess(0);
}
// Normal Code Here....
IsDebuggerPresent Using the PEBThe char IsDbgPresent = 0;
__asm {
mov eax, fs:[30h]
mov al, [eax + 2h]
mov IsDbgPresent, al
}
if(IsDbgPresent)
{
MessageBox(NULL, TEXT("Please close your debugging " +
"application and restart the program"),
TEXT("Debugger Found!"), 0);
ExitProcess(0);
}
// Normal Execution
CheckRemoteDebuggerPresentThis is another Win32 Debugging API function; it can be used to check if a remote process is being debugged. However, we can also use this as another method for checking if our own process is being debugged. For those of you who wonder how this function differs, BOOL IsDbgPresent = FALSE; CheckRemoteDebuggerPresent(GetCurrentProcess(), &IsDbgPresent); if(IsDbgPresent) { MessageBox(NULL, TEXT("Please close your debugging" + " application and restart the program"), TEXT("Debugger Found!"), 0); ExitProcess(0); } // Normal Execution NtQueryInformationProcessInstead of calling // Function Pointer Typedef for NtQueryInformationProcess typedef unsigned long (__stdcall *pfnNtQueryInformationProcess)(IN HANDLE, IN unsigned int, OUT PVOID, IN ULONG, OUT PULONG); // ProcessDebugPort const int ProcessDbgPort = 7; // We have to import the function pfnNtQueryInformationProcess NtQueryInfoProcess = NULL; // Other Vars unsigned long Ret; unsigned long IsRemotePresent = 0; HMODULE hNtDll = LoadLibrary(TEXT("ntdll.dll")); if(hNtDll == NULL) { // Handle however.. chances of this failing // is essentially 0 however since // ntdll.dll is a vital system resource } NtQueryInfoProcess = (pfnNtQueryInformationProcess) GetProcAddress(hNtDll, "NtQueryInformationProcess"); if(NtQueryInfoProcess == NULL) { // Handle however it fits your needs but as before, // if this is missing there are some SERIOUS issues with the OS } // Time to finally make the call Ret = NtQueryInfoProcess(GetCurrentProcess(), ProcessDbgPort, &IsRemotePresent, sizeof(unsigned long), NULL); if(Ret == 0x00000000 && IsRemotePresent != 0) { // Debugger is present MessageBox(NULL, TEXT("Please close your debugging " + "application and restart the program"), TEXT("Debugger Found!"), 0); ExitProcess(0); } NtGlobalFlag
unsigned long NtGlobalFlags = 0; __asm { mov eax, fs:[30h] mov eax, [eax + 68h] mov NtGlobalFlags, eax } if(NtGlobalFlags & 0x70) // 0x70 = FLG_HEAP_ENABLE_TAIL_CHECK | // FLG_HEAP_ENABLE_FREE_CHECK | // FLG_HEAP_VALIDATE_PARAMETERS { // Debugger is present MessageBox(NULL, TEXT("Please close your debugging " + "application and restart the program"), TEXT("Debugger Found!"), 0); ExitProcess(0); } // Normal execution Points of InterestThere is a lot more to anti-debugging in Windows, several methods such as using References
History
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||