⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbkfunc.c.svn-base

📁 这是一段游戏修改工具的源代码.ring3功能由dephi开发,驱动是C开发.希望对大家有帮助
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
//#include "C:\WINDDK\3790\inc\ifs\w2k\ntifs.h"
#include "DBKFunc.h"
#include "vmxhelper.h"

#ifndef AMD64
void interrupt1( void );
void interrupt3( void );
void interruptD1( void );
#endif

ULONG Int1Address;
ULONG Int3Address;
ULONG IntD1Address;
INT_VECTOR	NewInt1;
INT_VECTOR  NewIntD1;


unsigned __int64 readMSR(ULONG msr)
{
	ULONG a,b;
	__asm
	{
		push ecx
		push eax
		push edx
		mov ecx,msr
		rdmsr

		mov [a],eax
		mov [b],edx

		pop edx
		pop eax
		pop ecx
	}

	return ((INT64)b<<32) + a;
}

ULONG getCR3(void)
{
	ULONG cr3reg;
	__asm
	{
		mov eax,CR3
		mov cr3reg,eax
	}

	return cr3reg;

}

ULONG getCR4(void)
{
#ifndef AMD64
	ULONG cr4reg=0;
    __try
	{
		__asm
		{
			__emit 0x0f  //-|
			__emit 0x20  //-|-mov eax,cr4
			__emit 0xe0  //-|
			mov cr4reg,eax
		}
	}
	__except(1)
	{
		DbgPrint("Error getting CR4\n");
	}
	return cr4reg;
#else
	return 0;
#endif

}

void setCR4(ULONG cr4reg)
{
	__asm
	{
		mov eax,cr4reg
		__emit 0x0f  //-|
		__emit 0x22  //-|-mov cr4,eax
		__emit 0xe0  //-|			
	}
	return;
}

unsigned long long getTSC(void)
{
	ULONG a,b;
	unsigned long long result;
	__asm
	{
		push eax
		push edx
		rdtsc
		mov [a],eax
		mov [b],edx
		
		pop edx
		pop eax
	}

	result=a+((unsigned long long)(b) << 32);
	return result;
}

void StopDebugging(void)
{
	DebuggedProcessID=0;
	ChangeRegs[0].Active=FALSE;
	ChangeRegs[1].Active=FALSE;
	ChangeRegs[2].Active=FALSE;
	ChangeRegs[3].Active=FALSE;
	ChangeRegistersOnBP=FALSE;

	DbgPrint("Stopped the debugger\n");
	//the int hooks can stay, they don't hurt anyhow
}

void StopChangeRegOnBP(int DebugRegNR)
{
	int i;


	DbgPrint("DBKKERNEL:StopChangeRegOnBP %d\n",DebugRegNR);

	ChangeRegs[DebugRegNR].Active=FALSE;
	ChangeRegs[DebugRegNR].BreakAddress=0;

	for(i=0; i<4; i++)
	{
		if (ChangeRegs[DebugRegNR].Active)
		{
			ChangeRegistersOnBP=TRUE;
			DbgPrint("Still one debugreg active, so keep changing others\n" );
			return;
		}
	}

	ChangeRegistersOnBP=FALSE;

}

BOOLEAN ChangeRegOnBP(DWORD ProcessID, int DebugRegNR, PChangeReg CR)
{
	//This gets called just before the usermode app sets the debugreg
	//CR->Active ignored in this case, becomes true
	DbgPrint("Going to enable the debugger to set a change reg breakpoint on ProcessID %d(%x) for debugreg %d",ProcessID,ProcessID,DebugRegNR);
	CR->Active=TRUE;
	ChangeRegs[DebugRegNR]=*CR;
	ChangeRegs[DebugRegNR].Active=TRUE;
	DebuggedProcessID=ProcessID;	
	PsLookupProcessByProcessId((PVOID)ProcessID,&DebuggedProcessPEPROCESS);

	ChangeRegistersOnBP=TRUE;

	return TRUE; //always
}

BOOLEAN DebugProcess(DWORD ProcessID, DWORD Address, BYTE Length, BYTE RWE)
{
	DbgPrint("Going to debug a process for 1 process+debug address\nProcessID=%d (%x)\n",ProcessID,ProcessID);

	//EventsMissed=0;

	DebuggedProcessID=ProcessID;
	PsLookupProcessByProcessId((PVOID)ProcessID,&DebuggedProcessPEPROCESS);
	DebuggedAddress=Address;
	DebuggedAddressLength=Length;
	DebuggedAddressRWE=RWE;

	DbgPrint("DebuggedAddress=%x\n",DebuggedAddress);

	/*
	setting the debug registers in the context will be done from usermode (unless I figure out how to call 
	NtSetContextThread which doesn't seem to be in ntos so requires user32.sys which is fucking buggy to use
	but, the threadid's can be retrieved using a toolhelpsnapshot, (or a notify routine for created threads)
	and can be opened using OpenThread (win2k+ but I dont give a shit about that...)
	*/

	DbgPrint("Still here so I gues it works!\n");
	return TRUE;
}

unsigned short GetTR(void)
{
	unsigned short result;
#ifndef AMD64	
	__asm
	{
		STR AX
		mov result,ax
	}	
#endif;
	return result;
}

void GetGDT(PGDT pGdt)
{
#ifndef AMD64	
	__asm
	{
		MOV EAX, [pGdt]
		SGDT [EAX]
	}	
#endif;
}

void GetLDT(PGDT pLdt)
{
#ifndef AMD64	
	__asm
	{
		MOV EAX, [pLdt]
		SLDT [EAX]
	}	
#endif;
}

void GetIDT(PIDT pIdt)
{
	//I should do this for each logical processor
#ifndef AMD64	
	__asm
	{
		MOV EAX, [pIdt]
		SIDT [EAX]
	}	
#endif;
}

void SetIDT(PIDT pIdt)
{
	__asm
	{
		MOV EAX, [pIdt]
		LIDT [EAX]
	}
}

BOOLEAN HookInt1(void)
{
#ifndef AMD64
	IDT idt;

	//DbgPrint("Going to hook int1\n");
	GetIDT(&idt);

	__try
	{
		if (OriginalInt1.wHighOffset==0)
		{
			DebugReg7 DR_7;

			//DbgPrint("New hook, so storing the original Int1Handler\n");
            OriginalInt1=idt.vector[1];
			NewInt1=idt.vector[1];
			//NewIntD1=idt.vector[0xd1];

			Int1Address=idt.vector[1].wLowOffset+(idt.vector[1].wHighOffset << 16); //save the original address of the int3 handler
			NewInt1.wLowOffset=(WORD)&interrupt1;
			NewInt1.wHighOffset=(WORD)((DWORD)&interrupt1 >> 16);

			if (globaldebug)
			{
				//set the global debug bit and start tasksurfing
				__asm
				{
					mov eax,dr7
					mov DR_7,eax
				}
	
				DR_7.GD=1;
				__asm
				{
					mov eax,DR_7
					mov dr7,eax
				}
			}
			
		}

		//now overwrite the vector so it points to my handler
		//DbgPrint("Changing the vector to point to my handler\n");

		if (vmxusable)
		{
			DbgPrint("using VMX idt1 bypass\n");

			__try
			{
				vmx_redirect_interrupt1(1, 0, NewInt1.wSelector, (DWORD)&interrupt1); //idt bypass hook
			}
			__except(1)
			{
				DbgPrint("VMX idt1 bypass failed\n");
				return FALSE;
			}

		}
		else
		{
			__asm
			{
				PUSHFD //no idea why, I doubt it's usefull, but let's use it too....
				CLI
			}
			idt.vector[1]=NewInt1;
			__asm
			{
				STI
				POPFD
			}
		}


		return TRUE;
	}
	__except(1)
	{
		DbgPrint("Exception while hooking int1\n");
		return FALSE;
	}
#else
	return FALSE;
#endif
}


BOOLEAN HookInt3(void)
{
#ifndef AMD64
	IDT idt;
	//DbgPrint("Going to hook int3\n");
	GetIDT(&idt);

	__try
	{
		OriginalInt3=idt.vector[3];
		Int3Address=idt.vector[3].wLowOffset+(idt.vector[3].wHighOffset << 16); //save the original address of the int3 handler

		//now overwrite the vector so it points to my handler
		__asm
		{
			PUSHFD //no idea why, I doubt it's usefull, but let's use it too....
			CLI
		}

		idt.vector[3].wLowOffset=(WORD)&interrupt3;
		idt.vector[3].wHighOffset=(WORD)((DWORD)&interrupt3 >> 16);
		__asm
		{
			STI
			POPFD
		}
		//DbgPrint("Hooking int3 was successful\n");

	
		return TRUE;
	}
	__except(1)
	{
		DbgPrint("Exception while hooking int3\n");
		return FALSE;
	}
#else
	return FALSE;
#endif
}



int cpunr(void)
{
	unsigned int b;

	__asm
	{
		push eax
		push ebx
		push ecx
		push edx
		mov eax,1
		cpuid

		mov [b],ebx

		pop edx
		pop ecx
		pop ebx
		pop eax
	}

	return (b >> 24)+1;
}


struct {
	ULONG DR0;
	ULONG DR1;
	ULONG DR2;
	ULONG DR3;
	ULONG DR6;
	ULONG DR7;
} CPUDebugRegisterState[256]; //might optimize this in the future by allocating only the needed part... for now, fuck memory


ULONG r1,r2;
ULONG __stdcall GeneralHandler(IN ULONG iInt,IN PULONG Stacklocation )
{
#ifndef AMD64
/*	//check the current priviledge level
	DbgPrint("Welcome to my int handler. (I need to find out how this instruction gets me in ring0)\n");
	DbgPrint("Processid=%d (%x)\n",PsGetCurrentProcessId(),PsGetCurrentProcessId());
*/
	ULONG result=0;	//by default do handle the interrupt by the os
	ULONG DR_0,DR_1,DR_2,DR_3,ef;
	DebugReg6 DR_6;
	DebugReg7 DR_7;

	/*
	DbgPrint("Int1: CPUnr=%d",cpunr());	
	*/

	__asm{
        mov eax,dr0
		mov DR_0,eax
        mov eax,dr1
		mov DR_1,eax
        mov eax,dr2
		mov DR_2,eax
        mov eax,dr3
		mov DR_3,eax
        mov eax,dr6
		mov DR_6,eax
        mov eax,dr7
		mov DR_7,eax
		pushfd
		pop eax
		mov ef,eax
	};
	/*
	DbgPrint("Hello from int1\n");
	DbgPrint("eax=%x\n",Stacklocation[-1]);
	DbgPrint("ebx=%x\n",Stacklocation[-4]);
	DbgPrint("ecx=%x\n",Stacklocation[-2]);
	DbgPrint("edx=%x\n",Stacklocation[-3]);
	DbgPrint("esi=%x\n",Stacklocation[-7]);
	DbgPrint("edi=%x\n",Stacklocation[-8]);			
	DbgPrint("ebp=%x\n",Stacklocation[-6]);
	DbgPrint("ss=%x\n",Stacklocation[4]);
	DbgPrint("esp=%x\n",Stacklocation[3]);
	DbgPrint("eflags=%x\n",Stacklocation[2]);
	DbgPrint("cs=%x\n",Stacklocation[1]); //it was a break			
	DbgPrint("eip=%x\n",Stacklocation[0]); //it was a break			

	DbgPrint("DR0=%x\n",DR_0);
	DbgPrint("DR1=%x\n",DR_1);
	DbgPrint("DR2=%x\n",DR_2);
	DbgPrint("DR3=%x\n",DR_3);
	DbgPrint("DR6=%x\n",DR_6);
	DbgPrint("DR7=%x\n",DR_7);


	DbgPrint("Int1 DR6=%x DR7=%x int_eflags=%x\n",DR_6,DR_7,ef);*/
	
	
	if (globaldebug)
	{
		DR_7.GD=1; //re-set GD bit , but don't set it in the DR7 register yet


		if (DR_6.BD)
		{
			char *instruction=(char *)(Stacklocation[0]);
			int ip;
			int rm,reg;
			int id=cpunr();
			PEFLAGS flags;
			//gd bit is already 0 now
		
			flags=(PEFLAGS)(&Stacklocation[2]);
			//flags->RF=1;
			
			DR_6.BD=0;
			__asm
			{
				mov eax,DR_6
				mov dr6,eax
			}
				
				


			//check which instruction it is, read/write, has prefixes etc...
			//which registers used, and store that / retrieve it

			//0f 21 = read
			//0f 23 = write

			for (ip=0; instruction[ip]!=0x0f; ip++) ;

			reg=(instruction[ip+2] >> 3) & 7; //affected debug register
			rm=instruction[ip+2] & 7; //used general purpose register
		
	
			//get current cpu id to find out what drx should be or where to write the current state to

			if (instruction[ip+1] == 0x21)
			{
				
				//emulate read: rm,reg
				//return what the process has set it to
				switch (reg)
				{
					case 0:
						Stacklocation[-1-rm]=CPUDebugRegisterState[id].DR0; //-1-rm because it's a inverse and starts at -1
						break;

					case 1:
						Stacklocation[-1-rm]=CPUDebugRegisterState[id].DR1; 
						break;

					case 2:
						Stacklocation[-1-rm]=CPUDebugRegisterState[id].DR2; 
						break;

					case 3:
						Stacklocation[-1-rm]=CPUDebugRegisterState[id].DR3; 
						break;

					case 4:
						Stacklocation[-1-rm]=CPUDebugRegisterState[id].DR6; 
						break;

					case 5:
						Stacklocation[-1-rm]=CPUDebugRegisterState[id].DR7; 
						break;

					case 6:
						Stacklocation[-1-rm]=CPUDebugRegisterState[id].DR6; 
						break;

					case 7:
						Stacklocation[-1-rm]=CPUDebugRegisterState[id].DR7; 
						break;
				}
				
				

			}				
			else if (instruction[ip+1] == 0x23)
			{
				ULONG debugregvalue=Stacklocation[-1-rm];
				
				//emulate write: reg,rm
				switch (reg)
				{
					
					case 0:
						CPUDebugRegisterState[id].DR0=debugregvalue; //-1-rm because it's a inverse and starts at -1
						//and set the real register if allowed
						__asm
						{
							mov eax,debugregvalue
							mov dr0,eax
						}
						break;

					case 1:
						CPUDebugRegisterState[id].DR1=debugregvalue; 
						__asm
						{
							mov eax,debugregvalue
							mov dr1,eax
						}
						break;

					case 2:
						CPUDebugRegisterState[id].DR2=debugregvalue; 
						__asm
						{
							mov eax,debugregvalue
							mov dr2,eax
						}
						break;

					case 3:
						CPUDebugRegisterState[id].DR3=debugregvalue; 
						__asm
						{
							mov eax,debugregvalue
							mov dr3,eax
						}
						break;

					case 4:
						CPUDebugRegisterState[id].DR6=debugregvalue;
						__asm
						{
							mov eax,debugregvalue
							mov dr6,eax
						}
						break;

					case 5:
						CPUDebugRegisterState[id].DR7=debugregvalue;
						
						break;

					case 6:
						CPUDebugRegisterState[id].DR6=debugregvalue;
						__asm
						{
							mov eax,debugregvalue
							mov dr6,eax
						}
						break;

					case 7:
						CPUDebugRegisterState[id].DR7=debugregvalue;
						break;
						
				}
				
			}
			else
				DbgPrint("Something crappy has just happened\n");

			//if a global breakpoint is set check which debug breakpoint can be used and configure it
			//DebuggedAddress and DebuggedAddressLength

			*(ULONG *)&DR_7=CPUDebugRegisterState[id].DR7;
			DR_7.GD=1; //I could do a or operation in assembler, but i'm lazy

			if (DebuggedProcessID!=0)
			{
				__asm
				{
					mov eax,DebuggedAddress
					mov dr0,eax
				}
				DR_7.G0=1;
				DR_7.L0=1;
				DR_7.LEN0=3;
				DR_7.RW0=3;
			}

			__asm
			{
				mov eax,DR_7
				mov dr7,eax //don't touch debug regs now
			};

			
			Stacklocation[0]+=ip+3;
			return 1;
		}		
	}

	//DbgPrint("DebuggedProcessID==%d\n", DebuggedProcessID);
	if (DebuggedProcessID==0)
		return 0; //no debugging going on

	
	//DbgPrint("Int1: PsGetCurrentProcess()=%x DebuggedProcessPEPROCESS=%x\n", (ULONG)PsGetCurrentProcess(), (ULONG)DebuggedProcessPEPROCESS);
	

	
	if ((ULONG)PsGetCurrentProcess()==(ULONG)DebuggedProcessPEPROCESS)
	{
		//this is inside the memory of my debugged process
		//DbgPrint("(ULONG)PsGetCurrentProcess()==(ULONG)DebuggedProcessPEPROCESS\n");

		//DbgPrint("iInt=%d\n",iInt);
		if (iInt==1)
		{
			
			if ((ULONG)PsGetCurrentProcessId()!=DebuggedProcessID)
			{
				//different processid, probably caused by a keattachprocess
				//DbgPrint("Access by other process :%d\n",(ULONG)PsGetCurrentProcessId());

			}
		
			/*
			DbgPrint("Hello from int1\n");
			DbgPrint("eax=%x\n",Stacklocation[-1]);
			DbgPrint("ebx=%x\n",Stacklocation[-4]);
			DbgPrint("ecx=%x\n",Stacklocation[-2]);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -