Introduction
WINFO, a well known tool on the internet, can directly access I/O and memory. It applied Microsoft undocumented function (NATIVE API) to fetch I/O data. The design structure of PCI View is based on WDF as to simulate the function of WINFO to access I/O and memory.
Background
Knowledge of Win32 SDK is required.
Program Structure
PCI View can access I/O port and memory via IOMEM.DLL or the functions of DeviceIoControl
or ReadFile
/WriteFile
.
Introduction of Application
The API functions of READ_PORT_UCHAR(USHORT/ULONG)
or WRITE_PORT_UCHAR(USHORT/ULONG)
can be applied to access I/O port in Windows NT environment. The usages of API functions are similar to the functions provided by Runtime Library of C language, such as _outp
and _inp
.
case 1: if (pvInputBuffer->Command == 0) WRITE_PORT_UCHAR((PUCHAR)pvInputBuffer->PortBase, (UCHAR)pvInputBuffer->Data);
else
*(PUCHAR)pvOutputBuffer = READ_PORT_UCHAR((PUCHAR)pvInputBuffer->PortBase);
break;
case 2: if (pvInputBuffer->Command == 0)
WRITE_PORT_USHORT((PUSHORT)pvInputBuffer->PortBase, (USHORT)pvInputBuffer->Data);
else
*(PUSHORT)pvOutputBuffer = READ_PORT_USHORT((PUSHORT)pvInputBuffer->PortBase);
break;
case 4: if (pvInputBuffer->Command == 0)
WRITE_PORT_ULONG((PULONG)pvInputBuffer->PortBase, (ULONG)pvInputBuffer->Data);
else
*(PULONG)pvOutputBuffer = READ_PORT_ULONG((PULONG)pvInputBuffer->PortBase);
break;
The processing of memory is more complicated than the process of I/O which can be easily done by the API function.
- First of all, we need to get address and length where user would like to access in memory. Then,
MmMapIoSpace
function can map the address and length into a non-paged system space. - If the previous process is success, the allocations of
IoAllocateMdland MmBuildMdlForNonPagedPool
will be enough to be buffered to mapping the real memory. MmMapLockedPagesSpecifyCache
function can map the virtual memory to the caller. Therefore, the applications of RING 3 can directly fetch memory.
memReq.MapIo = MmMapIoSpace(Address, memReq.Length, MmNonCached);
if (memReq.MapIo == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
__leave;
};
memReq.Mdl = IoAllocateMdl(memReq.MapIo, memReq.Length, FALSE, FALSE, NULL);
if (memReq.Mdl == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
__leave;
};
MmBuildMdlForNonPagedPool(memReq.Mdl);
memReq.Buffer = (PUCHAR)MmMapLockedPagesSpecifyCache(memReq.Mdl,
UserMode, MmNonCached,
NULL,
FALSE,
NormalPagePriority);
if (memReq.Buffer == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
__leave;
};
The dynamic functions in real mode provide outp
, _outpw
, _outpd
, _inp
, _inpw
and _inpd
to access I/O port. There are 4 functions, such as MapMemory
, UnmapMemory
, ReadPhyicalMemory
and WritePhyicalMemory
, that can be used to fetch memory.
Function: designed to access the address and length of memory:
PUCHAR MapMemory(__in ULONG Address, __in ULONG Length);
Address : To access the beginning address of memory.
Length : To get the length of memory
The function will return the beginning address mapping in memory
when executed successfully.
Function: Release the assigned memory.
BOOLEAN UnmapMemory(VOID);
Sample Program
The application presents a sample to access IO-MEM. Without including DLL package, the application shows the information of the assigned memory or I/O port when directly calling IOMEM.DLL. The source code can be downloaded from http://bbs.codeheaven.com.tw/.
Sample:
History
- 26th April, 2010: Initial post