Mon 17 Jul 2006 04:26:21 PM UTC, original submission:
Hi,
Here is a code to enable user mode IO access in Windows without using any external driver. After enable_user_mode_io() is called, process can execute in/out calls.
Regards,
Zoltan
////////////////////////////////////////////////////////////
#include <windows.h>
#ifdef WIN32
static int enable_privilege(const char* priv)
{
int rc = -1;
HANDLE hToken;
LUID seValue;
TOKEN_PRIVILEGES tkPriv;
// Open process token
if (!OpenProcessToken(
GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken))
return -1;
if (!LookupPrivilegeValue(NULL, priv, &seValue))
goto cleanup;
tkPriv.PrivilegeCount = 1;
tkPriv.Privileges[0].Luid = seValue;
tkPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// Enable privilege
if (!AdjustTokenPrivileges(hToken, FALSE, &tkPriv, sizeof(tkPriv), NULL, NULL))
goto cleanup;
// Success
rc = 0;
cleanup:
CloseHandle(hToken);
return rc;
}
static int enable_user_mode_io()
{
typedef ULONG (__stdcall* PFn)(HANDLE, ULONG, PVOID, ULONG);
int rc = -1;
HMODULE hNtDll = NULL;
PFn fn;
ULONG nIOPL = 3;
// Find NTDLL.DLL
hNtDll = GetModuleHandle("ntdll.dll");
if (hNtDll == NULL)
// Failed to find NTDLL.DLL
return -1;
// Find ZwSetInformationProcess in NTDLL.DLL
fn = (PFn)GetProcAddress(hNtDll, "ZwSetInformationProcess");
if (fn == NULL)
return -1;
// Enable SE_TCB_NAME privilege
enable_privilege(SE_TCB_NAME);
// Set user mode IO access
if (fn(GetCurrentProcess(), 16, &nIOPL, sizeof(nIOPL)) != 0)
return -1;
return 0;
}
#if 1
int main(int argc, char** argv)
{
enable_user_mode_io();
// Test direct IO access
{
ULONG port = 0x378;
__asm mov edx, port
__asm in al, dx
}
return 0;
}
#endif
#endif // WIN32
|