Exetools  

Go Back   Exetools > General > General Discussion

Notices

Reply
 
Thread Tools Display Modes
  #1  
Old 02-28-2005, 01:13
0x539
 
Posts: n/a
beating IsDebuggerPresent for my unpacker

hi, could anybody explain me how to defeat IsDebuggerPresent?
i downloaded some sources of olly plugins but i dont understand
what they are actually doing. source code would be nice.
Reply With Quote
  #2  
Old 02-28-2005, 09:10
D-Jester's Avatar
D-Jester D-Jester is offline
VIP
 
Join Date: Nov 2003
Location: Ohio, USA
Posts: 269
Rept. Given: 39
Rept. Rcvd 61 Times in 41 Posts
Thanks Given: 0
Thanks Rcvd at 4 Times in 4 Posts
D-Jester Reputation: 61
Post Looking for this...?

Code Taken From: Guide on How to play with processes memory, write loaders and Oraculums

http://www.exetools.com/forum/showthread.php?t=6556

Many Thanks to Shub-Nigurrath

Code:
unsigned long KillisDebuggerPresent() 
{
	FARPROC addrIDP; //Buffer for API Address IsDebuggerPresent
	
	BYTE rdt[13]; //Buffer to read to (Total of 13 bytes)
    	BYTE wrt[3] = {0x33, 0xC0, 0xC3}; /*(Bytes to write (patch):
						33C0	xor eax, eax
						C3	ret
					  */
	unsigned long byteswritten=0;
	
	DWORD oldpr=0;
	
	HINSTANCE hKer;
	HANDLE hProcess = GetCurrentProcess();
	
	hKer = GetModuleHandle("KERNEL32");
	ZeroMemory(rdt,16);
	
	addrIDP = GetProcAddress(hKer, "IsDebuggerPresent");
	
	VirtualProtectEx(hProcess, (LPVOID)addrIDP, 3, PAGE_READONLY, &oldpr);
	ReadProcessMemory(hProcess, (LPVOID)addrIDP, (LPVOID)rdt, 13, NULL);
	VirtualProtectEx(hProcess, (LPVOID)addrIDP, 3, oldpr, &oldpr);
	
	// Check api signature
	if (rdt[0]==0x64 && rdt[1]==0xA1 && rdt[2]==0x18  && rdt[3]==0 && rdt[4]==0 && rdt[5]==0 && rdt[6]==0x8B && rdt[7]==0x40 && rdt[8]==0x30 && rdt[9]==0x0F && rdt[10]==0xB6 && rdt[11]==0x40 && rdt[12]==0x02) 
	{	
		__asm
		{
			add addrIDP, 9
		}
		
		VirtualProtectEx(hProcess, (LPVOID)addrIDP, 3, PAGE_READWRITE, &oldpr);
		WriteProcessMemory(hProcess, (LPVOID)addrIDP, (LPVOID)wrt, 3, &byteswritten);
		VirtualProtectEx(hProcess, (LPVOID)addrIDP, 3, oldpr, &oldpr);
	}
	return byteswritten;
}
Regards...
__________________
Even as darkness envelops and consumes us, wrapping around our personal worlds like the hand that grips around our necks and suffocates us, we must realize that life really is beautiful and the shadows of despair will scurry away like the fleeting roaches before the light.

Last edited by D-Jester; 02-28-2005 at 09:13.
Reply With Quote
  #3  
Old 02-28-2005, 13:36
TQN TQN is offline
VIP
 
Join Date: Apr 2003
Location: Vietnam
Posts: 358
Rept. Given: 143
Rept. Rcvd 24 Times in 13 Posts
Thanks Given: 196
Thanks Rcvd at 168 Times in 51 Posts
TQN Reputation: 24
I was not read the tutor of Shub-Nigurrath yet, but with the above code, I have a wonder: this function will be called from: the loader or the victim process.
Reply With Quote
  #4  
Old 02-28-2005, 20:00
dyn!o's Avatar
dyn!o dyn!o is offline
Friend
 
Join Date: Nov 2003
Location: Own mind
Posts: 214
Rept. Given: 1
Rept. Rcvd 1 Time in 1 Post
Thanks Given: 8
Thanks Rcvd at 0 Times in 0 Posts
dyn!o Reputation: 1
IsDebuggerPresent is the most weak anti-debug check.

If you want to defeat it then I would propose the following:

- modification of kernel32.dll (overwriting during the runtime)
- hooking the API itself (if the protection is more sophisticated and computes the checksum of it then usually it checks only first few instructions, you should be still able to set the hook at one of the last instructions inside this API)
- modification of IsDebuggerPresent return value in the code space of protected software (e.g. set a hardware breakpoint near the call offset)

Regards.

Last edited by dyn!o; 02-28-2005 at 20:02.
Reply With Quote
  #5  
Old 02-28-2005, 21:59
D-Jester's Avatar
D-Jester D-Jester is offline
VIP
 
Join Date: Nov 2003
Location: Ohio, USA
Posts: 269
Rept. Given: 39
Rept. Rcvd 61 Times in 41 Posts
Thanks Given: 0
Thanks Rcvd at 4 Times in 4 Posts
D-Jester Reputation: 61
Quote:
Originally Posted by TQN
I have a wonder: this function will be called from: the loader or the victim process.
The code example is the called from the victim. He asked how to defeat it, I'm not going to code it for him.

However with little to no modification this code or its equivalent could be used in combination with y0da's Force Library and thus IsDebuggerPresnt could be defeated via RemoteExec which enables you to execute code within the context of another process

Regards...
__________________
Even as darkness envelops and consumes us, wrapping around our personal worlds like the hand that grips around our necks and suffocates us, we must realize that life really is beautiful and the shadows of despair will scurry away like the fleeting roaches before the light.

Last edited by D-Jester; 02-28-2005 at 22:02.
Reply With Quote
  #6  
Old 03-01-2005, 02:28
Shub-Nigurrath's Avatar
Shub-Nigurrath Shub-Nigurrath is offline
VIP
 
Join Date: Mar 2004
Location: Obscure Kadath
Posts: 971
Rept. Given: 70
Rept. Rcvd 431 Times in 101 Posts
Thanks Given: 83
Thanks Rcvd at 405 Times in 127 Posts
Shub-Nigurrath Reputation: 400-499 Shub-Nigurrath Reputation: 400-499 Shub-Nigurrath Reputation: 400-499 Shub-Nigurrath Reputation: 400-499 Shub-Nigurrath Reputation: 400-499
absolutely correct, there are plenty ways to inject code into another one, directly in memory..

see the well known paper, just to start on this argument..

http://www.codeguru.com/Cpp/W-P/system/processesmodules/article.php/c5767
__________________
Ŝħůb-Ňìĝùŕřaŧħ ₪)
There are only 10 types of people in the world: Those who understand binary, and those who don't
http://www.accessroot.com
Reply With Quote
  #7  
Old 03-01-2005, 06:35
upb's Avatar
upb upb is offline
Friend
 
Join Date: Apr 2002
Location: Elbonia
Posts: 63
Rept. Given: 5
Rept. Rcvd 0 Times in 0 Posts
Thanks Given: 3
Thanks Rcvd at 0 Times in 0 Posts
upb Reputation: 0
another way, doesnt hook anything....

Code:
bool DisableBeingDebuggedFlag(HANDLE thread)
{
	CONTEXT ctx;

	ctx.ContextFlags = CONTEXT_SEGMENTS;
	if (!GetThreadContext(thread, &ctx))
	{
		error(FF "GetThreadContext(0x%08X)", FL, thread);
		return false;
	}

	LDT_ENTRY sel;
	if (!GetThreadSelectorEntry(thread, ctx.SegFs, &sel))
	{
		error(FF "GetThreadSelectorEntry(0x%08X)", FL, thread);
		return false;
	}

	DWORD fsbase = (sel.HighWord.Bytes.BaseHi << 8| sel.HighWord.Bytes.BaseMid) << 16 | sel.BaseLow;
	DWORD RVApeb;
	SIZE_T numread;

	if (!ReadProcessMemory(hproc, (LPCVOID)(fsbase + 0x30), &RVApeb, 4, &numread) || numread != 4)
	{
		error(FF "ReadProcessMemory(0x%08X, 0x%08X, 0x%08X, ...)", FL,
			hproc, (fsbase + 0x30), &RVApeb);
		return false;
	}

	WORD beingDebugged;
	if (!ReadProcessMemory(hproc, (LPCVOID)(RVApeb + 2), &beingDebugged, 2, &numread) || numread != 2)
	{
		error(FF "ReadProcessMemory(0x%08X, 0x%08X, 0x%08X, ...)", FL,
			hproc, RVApeb, &beingDebugged);
		return false;
	}

	beingDebugged = 0;

	if (!WriteProcessMemory(hproc, (LPVOID)(RVApeb + 2), &beingDebugged, 2, &numread) || numread != 2)
	{
		error(FF "ReadProcessMemory(0x%08X, 0x%08X, 0x%08X, ...)", FL,
			hproc, RVApeb, &beingDebugged);
		return false;
	}

	return true;
}

btw.... Shub-Nigurrath, is this needed for speed optimization or what ?:PPP
Quote:
__asm
{
add addrIDP, 9
}

Last edited by upb; 03-01-2005 at 06:43.
Reply With Quote
  #8  
Old 03-01-2005, 07:39
dyn!o's Avatar
dyn!o dyn!o is offline
Friend
 
Join Date: Nov 2003
Location: Own mind
Posts: 214
Rept. Given: 1
Rept. Rcvd 1 Time in 1 Post
Thanks Given: 8
Thanks Rcvd at 0 Times in 0 Posts
dyn!o Reputation: 1
Looks nice (logic). Anyway, won't work on 9x family.

Now, all hardcore maniacs, tell me why?

Regards.
Reply With Quote
  #9  
Old 03-01-2005, 09:02
upb's Avatar
upb upb is offline
Friend
 
Join Date: Apr 2002
Location: Elbonia
Posts: 63
Rept. Given: 5
Rept. Rcvd 0 Times in 0 Posts
Thanks Given: 3
Thanks Rcvd at 0 Times in 0 Posts
upb Reputation: 0
give me a kernel32.dll from 9x and i'll answer you hehe
(i dont have any laying around here and dont have any docs about win9x TIB, PEB(?!?) either).
Reply With Quote
  #10  
Old 03-01-2005, 16:53
dyn!o's Avatar
dyn!o dyn!o is offline
Friend
 
Join Date: Nov 2003
Location: Own mind
Posts: 214
Rept. Given: 1
Rept. Rcvd 1 Time in 1 Post
Thanks Given: 8
Thanks Rcvd at 0 Times in 0 Posts
dyn!o Reputation: 1
Hey, that would be too easy

You are accessing segment register to obtain the address of PEB and read process data. Since TEB (or TIB if you like) and PEB are well settled on WinNT clones but not on Win9x family, you have to be familiar with Win9x/WinNT kernels.

TEB is not a problem here because its field is the same on all Windows. The problematic topic in your example is PEB.

By using two additional APIs you will be able to add Win9x compatibility to the method you presented.

I made my homework. Who's next (to tell us which APIs I'm talking about or/and present another solution)?

Regards.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Beating a two session max! abitofboth General Discussion 6 04-14-2005 09:07


All times are GMT +8. The time now is 22:03.


Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX, chessgod101
( Since 1998 )