Log in

View Full Version : getting IDT


Shub-nigurrath
February 10th, 2006, 09:53
Hi,
I was trying to get the IDT values froma ring3 in WinXP with a peice of code such this one:

Code:

#pragma pack(1) // 2 works, too
typedef struct tagIDT
{
WORD wLimit;
DWORD dwBase;
} IDT, *PIDT;
#pragma pack()

VOID LoadIDT(OUT PIDT pIdt )
{
__asm {
MOV EAX, [pIdt] // load offset into EAX
SIDT [EAX]
}
}

#pragma pack(1)
typedef struct tagINT_VECTOR {
WORD wLowOffset; // LOWORD of the handler's offset
WORD wSelector; // selector of the handler's offset
BYTE bAccess; // 0-3: Type
// 4: ?(=0)
// 5-6: DPL
// 7: Present
BYTE wUnused; // 0, 0, 0, unused (binary)
WORD wHighOffset; // HIWORD of the handler's offset
} INT_VECTOR, *PINT_VECTOR;
#pragma pack()

VOID LoadINTVector( IN PIDT pIdt, IN UCHAR iVector, OUT PINT_VECTOR pVector ) {
__try {
DWORD dwBase = pIdt->dwBase + iVector * sizeof(INT_VECTOR);
memcpy( pVector, (const void *)dwBase, sizeof(INT_VECTOR) );
}
__except( 1 ) {
TRACE( "LoadINTVector failed: Exception\n" );
return;
}

TRACE( "LoadINTVector: Vector 0x%.2X successfully dumped\n", iVector);
}

int tst_IDT () {

IDT idt;
ULONG i=0x03; //breakpoint handler
INT_VECTOR Vec;
LoadIDT(&idt);
LoadINTVector( &idt, (UCHAR)i, &Vec);

//read the value corresponding to the breakpoint vector..

return 0;
}


but when I reach the memcpy call inside the LoadINTVector I get regularly an exception.

What I'm missing?

10x a lot in advance.

Maximus
February 10th, 2006, 20:52
mmh... I don't think Windows will allow you to do such thing so easily.
SIDT should return the 16+32/16+64 linear memory address, which is not the memory your task see.
Actually, 9/10 you get a c05 bc you access an address that is not allocated in your task view.

nikolatesla20
February 10th, 2006, 23:04
Yes, you can get IDT address but you won't be able to access the memory area without a driver that can do it for you. Also, I believe IDT contains the physical address and is not virtual mapped.

-nt20

Shub-nigurrath
February 11th, 2006, 08:49
I supposed so, then you can get where IDT is but cannot access that memory addresses outside ring0, isn't it?

nikolatesla20
February 11th, 2006, 09:40
Yep. For some reason the gidt is not a protected instruction when it really probably should have been. That's why you can use it to help detect if you are in a Virtual Machine o.s. or not. (at least in Virtual PC - VMWare does a little better "emulation" of this instruction..)

-nt20

Maximus
February 11th, 2006, 18:24
IDT address is in linear memory, not virtual. And it is not mapped to any task....
You can access Physical memory with admin privileges from r3 using the system phisical memory driver.

nikolatesla20
February 12th, 2006, 10:17
Quote:

Device\PhysicalMemory section object
Detailed description

In Windows Server 2003 SP1, user-mode access to the \Device\PhysicalMemory object is not permitted. All forms of access (read, write) are refused when the \Device\PhysicalMemory object is accessed from a user-mode application. Access to the \Device\PhysicalMemory object is refused regardless of the user context (Administrators, Users, Local System, etc.) the application is running in.

Kernel-mode (driver) access to the \Device\PhysicalMemory object is unchanged for Windows Server 2003 SP1.

There are no means to revert this changed behavior in Windows Server 2003 SP1.
Why is this change important? What threats does it help mitigate?

This change was made to help prevent security exploits that might leverage the functionality of the \Device\PhysicalMemory object from user-mode.

In previous versions of Windows, access to the \Device\PhsyicalMemory object was protected by an access control list (ACL). However, the ACL may be inadvertently changed. Refusing all access to the \Device\PhysicalMemory object from user-mode ensures this scenario cannot occur.


...

Maximus
February 12th, 2006, 12:50
Damn!!
mmh... did they not even allow read from SYSTEM account?
(on XP, however, it is fine for now)

omega_red
February 13th, 2006, 04:12
As for getting IDT with PhysicalMemory object, you can take a look at my messy code here: http://ry.pl/~omega/asm/sdt.zip
Seems to still work on xp sp2, but on 2003 server sp1 it's Access Denied at NtOpenSection.

If you want an example of a driver that makes any memory accessible to ring3, see here: http://ry.pl/~omega/progs/syscall.zip
Its usage is simple: after
Code:
CreateFile("\\\\.\\MemMap", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

you do WriteFile with two dwords: 0 (command id, only 0 supported for now , and the virtual address you want access. Then you just do ReadFile in page size.

Shub-nigurrath
February 13th, 2006, 06:11
10x for the code omega_red I will check it...

NeOXOeN
February 13th, 2006, 20:20
Shub-nigurrath you have very nice source code about getting IDT on yates site...

bye

Shub-nigurrath
February 14th, 2006, 05:38
BTW I found this interesting paper:
http://www.codeproject.com/system/interrupthook.asp