📄 pokeio.c
字号:
/*********************************************************************
This code fragment illustrates the unsuccessful attempt to directly
modify the IOPM base address. This code would appear in a kernel
mode device driver. Refer to the GIVEIO.C listing for a complete
device driver example.
*********************************************************************/
/*
* Make sure our structure is packed properly, on byte boundary, not
* on the default doubleword boundary.
*/
#pragma pack(push,1)
/*
* Structure of a GDT (global descriptor table) entry. From
* processor manual.
*/
typedef struct {
unsigned limit : 16;
unsigned baselo : 16;
unsigned basemid : 8;
unsigned type : 4;
unsigned system : 1;
unsigned dpl : 2;
unsigned present : 1;
unsigned limithi : 4;
unsigned available : 1;
unsigned zero : 1;
unsigned size : 1;
unsigned granularity : 1;
unsigned basehi : 8;
} GDTENT;
/*
* Structure of the 48 bits of the GDT register that are stored
* by the SGDT instruction.
*/
typedef struct {
unsigned short limit;
GDTENT *base;
} GDTREG;
#pragma pack(pop)
/*
* This code demonstrates the brute force approach to modifying
* the IOPM base. The IOPM base is stored as a two byte integer
* at offset 0x66 within the TSS, as documented in the processor
* manual. In Windows NT, the IOPM is stored within the TSS
* starting at offset 0x88, and going for 0x2004 bytes. This is
* not documented anywhere, and was determined by inspection.
* The code here puts some 0's into the IOPM so that we
* can try to access some I/O ports, then modifies the IOPM base
* address.
*
* This code is unsuccessful because NT overwrites the IOPM
* base on each process switch.
*/
void GiveIO()
{
GDTREG gdtreg;
GDTENT *g;
short TaskSeg;
char *TSSbase;
int i;
_asm str TaskSeg; // get the TSS selector
_asm sgdt gdtreg; // get the GDT address
g = gdtreg.base + (TaskSeg >> 3); // get the TSS descriptor
// get the TSS address
TSSbase = (PVOID)(g->baselo | (g->basemid << 16)
| (g->basehi << 24));
for(i=0; i < 16; ++i) // poke some 0's into the
TSSbase[0x88 + i] = 0; // IOPM
// set IOPM base to 0x88
*((USHORT *)(TSSbase + 0x66)) = 0x88;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -