首页
社区
课程
招聘
[求助]无驱动 进入ring0
发表于: 2009-3-3 14:58 5652

[求助]无驱动 进入ring0

2009-3-3 14:58
5652
731K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3y4G2k6r3g2H3M7X3!0B7k6h3y4@1i4K6u0W2j5$3!0E0i4K6u0r3d9@1u0Q4x3V1k6K6P5i4y4@1k6h3#2Q4x3V1k6K6L8%4k6A6k6i4c8Q4y4h3k6C8k6i4u0F1k6h3I4Q4y4h3k6Z5j5h3y4C8i4K6u0W2j5i4y4H3P5l9`.`.
小弟正在看上面的帖子,想让其支持PAE下的页目录查找,无奈改了半天代码没看到效果 ,现贴出来求助,哪位大牛可否指正一下 不胜感激~~~

// irqs.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include <assert.h>

MapViewOfSection NtMapViewOfSection;
UnmapViewOfSection NtUnmapViewOfSection;
OpenSection NtOpenSection;
Close NtClose;

USHORT selector; 

HANDLE event;


void kernelfunction(DWORD usercs,DWORD irq)
{

	DWORD absent =0; BYTE gdtr[8];


	//check if ioapic is present and enabled
	if(irq<=23)
	{
		_asm 
		{
			mov eax,1 ;
			cpuid ;
			and edx, 0x00000200 ;
			cmp edx,0 ;
			jne skip1 ;
			mov absent,1 ;
skip1:
			mov ecx,0x1b ;
			rdmsr ;
			and eax,0x00000800 ;
			cmp eax,0 ;
			jne skip2 ;
			mov absent,1 ;
		}

		//if APIC is enabled, get vector from it and return
skip2:
		if(!absent)
		{
			//map ioapic - make sure that we map it to non-cached memory. Certainly,we have to do it only
			//upon the function's very first invocation, i.e. when irq is 0	 	 

			if(!irq)
			{


				_asm 
				{

					mov ebx,0xfec00000 ;
					or ebx,0x13 ;
					mov eax,0xc0000000 ;
					mov dword ptr[eax],ebx ;
				}
			}

			//now we are about to get interrupt vector
			PULONG array=NULL;

			//write 0x10+2*irq to IOREGSEL
			array[0]=0x10+2*irq;

			// subsequent read from IOWIN returns 32 low-order bits of Redirection Table that corresponds to our IRQ. 
			// 8 low-order bits are interrupt vector, corresponding to our IRQ 
			DWORD vector=(array[4]&0xff);

			// return interrupt vector. Dont forget that we must return with RETF, and pop 4 bytes
			// off the stack
			_asm
			{
				mov eax,vector ;
				mov esp,ebp ;
				pop ebp ;
				retf 4 ;
			}

		}
	}

	//either apic is not supported, or irq is above 23,i.e. this is the last invocation
	//therefore, clean up gdt and return 500 -the caller knows how to interpret it this value
	_asm
	{
		//clean up gdt
		sgdt gdtr ;
		lea eax,gdtr ;
		mov ebx,dword ptr[eax+2] ;
		mov eax,0 ;
		mov ax,selector ;
		shl eax,3 ;
		add ebx,eax ;
		mov dword ptr[ebx],0 ;
		mov dword ptr[ebx+4],0 ;

		// adjust stack and return
		mov eax,500 ;
		mov esp,ebp ;
		pop ebp ;
		retf 4 ;
	}


} 
void go()
{

	EXPLICIT_ACCESS Access;
	PACL OldDacl=NULL, NewDacl=NULL;
	PVOID security;
	HANDLE Section; 
	NTSTATUS status; 
	INIT_UNICODE_STRING(name, L"\\Device\\PhysicalMemory");
	OBJECT_ATTRIBUTES oa ={sizeof(oa),0,&name,0,0,0};  

	memset(&Access, 0, sizeof(EXPLICIT_ACCESS));
	NtOpenSection(&Section, WRITE_DAC | READ_CONTROL, &oa);

	GetSecurityInfo(Section, SE_KERNEL_OBJECT, 
		DACL_SECURITY_INFORMATION, NULL, NULL, &OldDacl,
		NULL, &security);

	Access.grfAccessPermissions = SECTION_ALL_ACCESS; 
	Access.grfAccessMode        = GRANT_ACCESS;
	Access.grfInheritance       = NO_INHERITANCE;
	Access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
	Access.Trustee.TrusteeForm  = TRUSTEE_IS_NAME;
	Access.Trustee.TrusteeType  = TRUSTEE_IS_USER;
	Access.Trustee.ptstrName = "CURRENT_USER";

	// update ACL
	SetEntriesInAcl(1, &Access, OldDacl, &NewDacl);


	SetSecurityInfo(Section, SE_KERNEL_OBJECT,
		DACL_SECURITY_INFORMATION, NULL, NULL, NewDacl, 
		NULL);


	CloseHandle(Section);

	//check how much RAM we've got
	MEMORYSTATUS meminfo;
	GlobalMemoryStatus(&meminfo);

	//get handle to RAM

	status = NtOpenSection(&Section,SECTION_MAP_READ|SECTION_MAP_WRITE,&oa);


	DWORD found=0,MappedSize,x;
	LARGE_INTEGER phys;
	DWORD* entry,*pteEntry;  
	PVOID DirectoryMappedAddress,TableMappedAddress; 
	DWORD DirectoryOffset,TableOffset;

	for(x=0;x<meminfo.dwTotalPhys;x+=0x1000)
	{
		//map current page in RAM
		MappedSize=4096;
		phys.QuadPart=x;
		DirectoryMappedAddress=0;

		status = NtMapViewOfSection(Section, (HANDLE) -1, &DirectoryMappedAddress, 0L,MappedSize, &phys, &MappedSize, ViewShare,0, PAGE_READONLY);
		if(status)
			continue;

		entry=(DWORD*)DirectoryMappedAddress;

		//get offsets
		DirectoryOffset=(DWORD)DirectoryMappedAddress;
		TableOffset=(DWORD)DirectoryMappedAddress;
		DirectoryOffset>>=22;
		TableOffset=(TableOffset>>12)&0x3ff;
		if((entry[0x301]&1)!=1 || (entry[DirectoryOffset]&1)!=1)
		{
			NtUnmapViewOfSection((HANDLE) -1, DirectoryMappedAddress);
			continue;
		}

		MappedSize=4096;
		phys.QuadPart=(entry[0x301]&0xfffff000);
		TableMappedAddress=0;
		status = NtMapViewOfSection(Section, (HANDLE) -1, &TableMappedAddress, 0L,MappedSize, &phys, &MappedSize, ViewShare,0, PAGE_READONLY);
		if(status)
		{
			NtUnmapViewOfSection((HANDLE) -1, DirectoryMappedAddress);
			continue;
		}

		pteEntry = (DWORD*)TableMappedAddress;
		if((pteEntry[0x200]&0xfffff000)!=x || (pteEntry[0x200]&1)!=1)
		{
			NtUnmapViewOfSection((HANDLE) -1, DirectoryMappedAddress);
			NtUnmapViewOfSection((HANDLE) -1, TableMappedAddress);
			continue;
		}
		NtUnmapViewOfSection((HANDLE) -1, TableMappedAddress);

		MappedSize=4096;
		phys.QuadPart=(entry[DirectoryOffset]&0xfffff000);
		TableMappedAddress=0;
		status = NtMapViewOfSection(Section, (HANDLE) -1, &TableMappedAddress, 0L,MappedSize, &phys, &MappedSize, ViewShare,0, PAGE_READONLY);
		if(status)
		{
			NtUnmapViewOfSection((HANDLE) -1, DirectoryMappedAddress);
			continue;
		}

		//now let's check if this is really a page table If yes, 20 upper bits of (V>>12)&0x3ff-th 
		//entry must be equal to P, and Present bit must be set in this entry. If the above is true, 
		// P is really a page directory 
		entry=(DWORD*)TableMappedAddress;
		if((entry[TableOffset]&1)==1 && (entry[TableOffset]&0xfffff000)==x)
			found++;

		NtUnmapViewOfSection((HANDLE) -1, TableMappedAddress);

		//directory is found - no need to proceed further
		if(found)
			break;

		NtUnmapViewOfSection((HANDLE) -1, DirectoryMappedAddress);  
	}
	assert(found != 0);
	//get base address of gdt

	BYTE gdtr[8]; 
	DWORD gdtbase,physgdtbase; 
	_asm
	{
		sgdt gdtr ;
		lea eax,gdtr ;
		mov ebx,dword ptr[eax+2] ;
		mov gdtbase,ebx ;
	}


	//get directory and table offsets
	DirectoryOffset=gdtbase;TableOffset=gdtbase;
	DirectoryOffset>>=22;TableOffset=(TableOffset>>12)&0x3ff;

	entry=(DWORD*)DirectoryMappedAddress;

	//map page table - phys. address of it is 20 upper bits of (V-22)-th entry of page directory
	MappedSize=4096; phys.QuadPart=(entry[DirectoryOffset]&0xfffff000); TableMappedAddress=0;
	status = NtMapViewOfSection(Section, (HANDLE) -1, &TableMappedAddress, 0L,MappedSize, &phys, &MappedSize, ViewShare,0, PAGE_READONLY);

	//phys page is in 20 upper bits of (V>>12)&0x3ff-th entry of page table- this is what we need
	entry=(DWORD*)TableMappedAddress;
	physgdtbase=(entry[TableOffset]&0xfffff000);
	//unmap everything
	NtUnmapViewOfSection((HANDLE) -1, TableMappedAddress);

	NtUnmapViewOfSection((HANDLE) -1, DirectoryMappedAddress);

	//now let's map gdt
	PBYTE GdtMappedAddress=0;phys.QuadPart=physgdtbase;MappedSize=4096;
	NtMapViewOfSection(Section, (HANDLE) -1, (PVOID*)&GdtMappedAddress, 0L,MappedSize, &phys, &MappedSize, ViewShare,0, PAGE_READWRITE);
	gdtbase&=0xfff;
	GdtMappedAddress+=gdtbase;

	CallGateDescriptor * gate=(CallGateDescriptor * )GdtMappedAddress;

	//now let's find free entry in GDT. Type of current gdt entry does not matter - Present
	// bit is 48-th bit for all type of descriptors, so we interpret all descriptors as call gates
	selector=1;
	while(1)
	{
		if(!gate[selector].present)break;
		selector++;
	}

	// now let's set up a call gate
	gate[selector].offset_low  = (WORD) ((DWORD)kernelfunction & 0xFFFF);
	gate[selector].selector     = 8;
	gate[selector].param_count  = 1; //we will pass a parameter
	gate[selector].unused    = 0;
	gate[selector].type       = 0xc;     // 32-bit callgate 

	gate[selector].dpl          = 3;      // must be 3
	gate[selector].present      = 1;
	gate[selector].offset_high = (WORD) ((DWORD)kernelfunction >> 16);


	//we don't need physical memory any more
	NtUnmapViewOfSection((HANDLE) -1, GdtMappedAddress);
	CloseHandle(Section);

	// now we will get interrupt vectors
	DWORD res; 
	DWORD resultarray[24];
	ZeroMemory(resultarray,sizeof(resultarray));

	for (x=0;x<25;x++)
	{

		//let's call the function via the call gate. Are you ready???

		WORD   farcall[3];
		farcall[2] = (selector<<3); 
		_asm
		{

			mov ebx,x ;
			push ebx ;
			call fword ptr [farcall] ;
			mov res,eax ;

		}

		if(x==24)
			break;
		//if the return value is 500 and this was not the final invocation, apic is not present
		//inform the user about it, and that't it - it does not make sense to proceed with the loop
		if(res==500)
		{
			MessageBox(GetDesktopWindow()," APIC is not supported","IRQs",MB_OK);
			break;
		}

		resultarray[x]=res;
	}

	// inform the user
	for (x=0;x<24;x++)
	{
		res=resultarray[x];
		//if irq is not present, the return value is 0xFF, so proceed to the next entry
		// if apic is not ebabled, the whole array is still filled with zeroes
		if(res==0xff || res==0)
			continue;

		// inform the user about mapping of current IRQ
		char numbuff[8]; 
		char buff[64];
		strcpy(buff,"IRQ");
		sprintf(numbuff,"%d\n",x);
		strcat(buff,numbuff);

		DWORD a=strlen(buff);
		buff[a-1]='\0';
		strcat(buff," maps to vector ");
		sprintf(numbuff,"%X\n",res);
		strcat(buff,numbuff);
		a=strlen(buff);
		buff[a-1]='\0';
		MessageBox(GetDesktopWindow(),buff,"IRQs",MB_OK);

	}

	SetEvent(event);
}




int APIENTRY WinMain(HINSTANCE hInstance,
					 HINSTANCE hPrevInstance,
					 LPSTR     lpCmdLine,
					 int       nCmdShow)
{

	NtMapViewOfSection=(MapViewOfSection)GetProcAddress(GetModuleHandle("ntdll.dll"),"NtMapViewOfSection");	
	NtUnmapViewOfSection=(UnmapViewOfSection)GetProcAddress(GetModuleHandle("ntdll.dll"),"NtUnmapViewOfSection");	
	NtOpenSection=(OpenSection)GetProcAddress(GetModuleHandle("ntdll.dll"),"NtOpenSection");	
	NtClose=(Close)GetProcAddress(GetModuleHandle("ntdll.dll"),"NtClose");

	event=CreateEvent(0,0,0,"event");
	DWORD dw;

	HANDLE thread=CreateThread(0,0,(LPTHREAD_START_ROUTINE)go,0,CREATE_SUSPENDED,&dw);

	SetThreadAffinityMask (thread,1);
	ResumeThread(thread);
	WaitForSingleObject(event,INFINITE);
	// TODO: Place code here.

	return 0;
}


[培训]科锐逆向工程师培训第53期2025年7月8日开班!

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
int64 mmgetphyscaladdress
{
	int offset = baseaddress&0xfff;
	int baseaddress1 = *((baseaddress>>20)&0xffc+0xc0300000);
	if(baseaddress1&0x81)
	{
		int baseaddress2 = baseaddress1;
		baseaddress1 = (baseaddress>>12)&0x3ff);
		baseaddress2>>=12;
		baseaddress1 = baseaddress1+baseaddress2;

		int64 phadd = baseaddress1<<12+offset;
		return phadd;

	}
	else
	{
		if(baseaddress1&0x1)
		{
			baseaddress1 = *((baseaddress>>10)&0x3ffffc)+0xc0000000);
			if(baseaddress1&0x1)
			{
				if(baseaddress1>>12)
				{
					int64 phadd = baseaddress1<<12+offset;
					return phadd;
				}
			}
		}
	}
	return NULL;
}
2009-3-10 00:28
0
游客
登录 | 注册 方可回帖
返回