News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Where is Ke386QueryIoAccessMap?

Started by UtillMasm, February 03, 2010, 03:25:16 PM

Previous topic - Next topic

UtillMasm

Windows SDK & WDK: no!
i need a online website.
:'(


Ficko

#2
What you are trying to do is write a kernel mode device driver.
Not easy. :bg

But you can accomplish the same thing on user level.

The proc bellow returns TRUE on success and you can "talk" to ports directly after calling it once.


; ---------------------------------------------------------------------------
MAXIMUM_ALLOWED     equ 2000000h
ProcessUserModeIOPL    equ 16
READ_CONTROL    equ 20000h
WRITE_DAC     equ 40000h
DACL_SECURITY_INFORMATION   equ 4
SE_KERNEL_OBJECT    equ 6
TOKEN_ASSIGN_PRIMARY     equ 1
TOKEN_DUPLICATE          equ 2
TOKEN_QUERY              equ 8
GRANT_ACCESS    equ 1
TRUSTEE_IS_SID    equ 0
TH32CS_SNAPPROCESS       equ 2
MAX_PATH                    equ 260
INVALID_HANDLE_VALUE        equ -1
; ---------------------------------------------------------------------------
TRUSTEE_A STRUCT
pMultipleTrustee   DWORD ?
MultipleTrusteeOperation DWORD ?
TrusteeForm     DWORD ?
TrusteeType     DWORD ?
ptstrName     DWORD ?
TRUSTEE_A ENDS
EXPLICIT_ACCESS STRUCT
grfAccessPermissions DWORD   ?
grfAccessMode   DWORD  ?
grfInheritance   DWORD  ?
Trustee     TRUSTEE_A <>
EXPLICIT_ACCESS ENDS
PROCESSENTRY32 STRUCT
    dwSize              DWORD ?
    cntUsage            DWORD ?
    th32ProcessID       DWORD ?
    th32DefaultHeapID   DWORD ?
    th32ModuleID        DWORD ?
    cntThreads          DWORD ?
    th32ParentProcessID DWORD ?
    pcPriClassBase      DWORD ?
    dwFlags             DWORD ?
    szExeFile           db MAX_PATH dup(?)
PROCESSENTRY32 ENDS
; ---------------------------------------------------------------------------
.const
S1   db "S-1-1-0",0
WinLogOn db "WINLOGON.EXE",0
.code
; SetIOPLto3(),DWORD
; =============== S U B R O U T I N E =======================================
SetIOPLto3 proc uses esi edi
LOCAL IOPL  :DWORD
LOCAL m_hToken :DWORD
LOCAL hToken :HANDLE
LOCAL pAcl  :POINTER
LOCAL pAclMod :POINTER
LOCAL ea  :EXPLICIT_ACCESS
LOCAL procEntry :PROCESSENTRY32
call GetWinLogon
.if (eax != 0)
  invoke OpenProcess, MAXIMUM_ALLOWED,FALSE,eax
  .if (eax != 0)
   xchg esi, eax    ;ESI = hProcess
   invoke OpenProcessToken, esi,READ_CONTROL OR WRITE_DAC,ADDR hToken
   xor edi, edi
   mov m_hToken, edi
   inc edi
   .if (eax != 0)
    xor ecx, ecx
    invoke GetSecurityInfo ,hToken,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,ecx,ecx,ADDR pAcl,ecx,ecx
    .if (eax == 0)
     invoke RtlZeroMemory, ADDR ea,SIZEOF ea
     mov ea.grfAccessPermissions, TOKEN_QUERY OR TOKEN_DUPLICATE OR TOKEN_ASSIGN_PRIMARY
     mov ea.grfAccessMode, GRANT_ACCESS
     mov ea.Trustee.TrusteeForm, TRUSTEE_IS_SID
     invoke ConvertStringSidToSid ,ADDR S1,ADDR ea.Trustee.ptstrName
     .if (eax != 0)
      invoke SetEntriesInAcl,1,ADDR ea,pAcl,ADDR pAclMod
      .if (eax == 0)
       invoke SetSecurityInfo, hToken,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,eax,eax,pAclMod,eax
       xchg edi, eax
      .endif
      invoke LocalFree, ea.Trustee.ptstrName
     .endif
    .endif
    invoke CloseHandle, hToken
   .endif
   .if (edi == 0)
    invoke OpenProcessToken, esi,MAXIMUM_ALLOWED,ADDR m_hToken
   .endif
   invoke CloseHandle, esi
   mov eax, m_hToken
   .if (eax != 0)
    invoke ImpersonateLoggedOnUser, eax
    .if (eax != 0)
     invoke GetCurrentProcess
     xchg ecx, eax
     mov IOPL, 3
     invoke ZwSetInformationProcess, ecx,ProcessUserModeIOPL,ADDR IOPL,SIZEOF IOPL
     .if (eax == 0)
      inc eax
     .endif
    .endif
   .endif
  .endif
.endif
ret
; =============== S U B R O U T I N E =======================================
GetWinLogon:invoke CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS,0
   .if (eax != INVALID_HANDLE_VALUE)
    xchg edi, eax
    lea esi, procEntry
    mov [esi].PROCESSENTRY32.dwSize, SIZEOF PROCESSENTRY32
    invoke Process32First, edi,esi
    .if (eax != 0)
     invoke Process32Next, edi,esi
     .while (eax != 0)
      Invoke CharUpper,ADDR [esi].PROCESSENTRY32.szExeFile
      Invoke lstrcmp,ADDR [esi].PROCESSENTRY32.szExeFile,offset WinLogOn
      test eax, eax
      .if (!ZERO?)
       invoke Process32Next, edi,esi
      .else
       mov eax, [esi].PROCESSENTRY32.th32ProcessID
       retn
      .endif
     .endw
    .endif
   .else
    inc eax 
   .endif
   retn
SetIOPLto3 endp
end

UtillMasm

 :U
i need a full Windows netive API (or Routine) document website.
nobody collect this stuff? :bg


UtillMasm

 :snooty:
Ke386QueryIoAccessMap is not in there.

Ficko

That's an undocumented call. :wink

If you like secrets: :bg

http://undocumented.rawol.com


UtillMasm

 :U
(but also no Ke386QueryIoAccessMap... mybe i can write my personal document.  :green)

Astro

Hi,

Wasn't there an insight into it in the links I posted? The code examples make use of it.

Not sure what you're looking for...

If all else fails... I can't suggest it though.  :wink

Here is another link: http://www.beyondlogic.org/porttalk/porttalk.htm

QuoteManipulating the IOPM (I/O Permission Bitmap)

Changing the IOPM within your Kernel Mode Drivers requires the knowledge of a couple of undocumented calls. These are Ke386IoSetAccessProcess, Ke386SetIoAccessMap and PsLookupProcessByProcessId.

   PsLookupProcessByProcessId(IN ULONG ulProcId,OUT struct _EPROCESS ** pEProcess);

The IOPM routines use a Pointer to Process and not the ProcessID. Therefore our first task is to convert the ProcessID to a Pointer to Process. There are documented calls such as PsGetCurrentProcess(), however we don't want the current process but rather the pointer to process of the process we wish to grant access to. This information is passed to the driver in the form of a processID. We must then use the undocumented call PsLookupProcessByProcessId to convert our ProcessID to a Pointer to Process.

Once we have a Pointer to Process we can start manipulating the I/O permission bitmap using the following undocumented calls

   void Ke386SetIoAccessMap(int, IOPM *);
   void Ke386QueryIoAccessMap(int, IOPM *);
   void Ke386IoSetAccessProcess(PEPROCESS, int);


Ke386SetIoAccessMap will copy the IOPM specified to the TSS. Ke386QueryIoAccessMap will read it from the TSS. The IOPM is a 8192 byte array specifying which ports are allowed access and which ones aren't. Each address is represented by one bit, thus the 8192 bytes will specify access up to 64K. Any zero bit will allow access, while a one will deny access.

After the IOPM has been copied to the TSS, the IOPM offset pointer must be adjusted to point to our IOPM. This is done using the Ke386IoSetAccessProcess. The int parameter must be set to 1 to enable it to be set. Calling the function with zero will remove the pointer.

Best regards,
Robin.

redskull

Assuming you have Windbg with symbols (from the command line):

kd -kl -c "u nt!Ke386QueryIoAccessMap L24"

No such thing as an undocumented function for an assembly language programmer  :8)

Strange women, lying in ponds, distributing swords, is no basis for a system of government

Astro

I was going to suggest disassembling/reverse engineering it... not sure if I can say that...  :bdg :eek

Best regards,
Robin.

UtillMasm

i have the 'ntoskrnl.exe' sources(masm & c: wrk v1.2).

i don't have WinDbg usage & API(or Function or Routine) document.

your replys are very useful.

you are all document guy & program guy! :U

UtillMasm

wrk v1.2BOOLEAN
Ke386QueryIoAccessMap (
    ULONG MapNumber,
    PKIO_ACCESS_MAP IoAccessMap
    )

/*++

Routine Description:

    The specified i/o access map will be dumped into the buffer.
    map 0 is a constant, but will be dumped anyway.

Arguments:

    MapNumber - Number of access map to set.  map 0 is fixed.

    IoAccessMap - Pointer to buffer (64K bits, 8K bytes) which
           is to receive the definition of the access map.
           Must be in non-paged pool.

Return Value:

    TRUE if successful.  FALSE if failure (attempt to query a map
    which does not exist)

--*/

{

    ULONG i;
    PVOID Map;
    KIRQL OldIrql;
    PUCHAR p;

    //
    // Reject illegal requests
    //

    if (MapNumber > IOPM_COUNT) {
        return FALSE;
    }


    //
    // Copy out the map
    //

    if (MapNumber == IO_ACCESS_MAP_NONE) {

        //
        // no access case, simply return a map of all 1s
        //

        p = (PUCHAR)IoAccessMap;
        for (i = 0; i < IOPM_SIZE; i++) {
            p[i] = (UCHAR)-1;
        }

    } else {

        //
        // Raise to DISPATCH_LEVEL to obtain read access to the structure
        //

        KeRaiseIrql (DISPATCH_LEVEL, &OldIrql);

        //
        // normal case, just copy the bits
        //

        Map = (PVOID)&(KiPcr ()->TSS->IoMaps[MapNumber-1].IoMap);
        RtlCopyMemory ((PVOID)IoAccessMap, Map, IOPM_SIZE);

        //
        // Restore IRQL.
        //

        KeLowerIrql (OldIrql);
    }

    return TRUE;
}

MS documented as comment, asshole... :boohoo:

dedndave

you are document guy !!!!   :P
Quote
void Ke386SetIoAccessMap(int, IOPM *);
void Ke386QueryIoAccessMap(int, IOPM *);
void Ke386IoSetAccessProcess(PEPROCESS, int);

Ke386SetIoAccessMap will copy the IOPM specified to the TSS. Ke386QueryIoAccessMap will read it from the TSS. The IOPM is a 8192 byte array specifying which ports are allowed access and which ones aren't. Each address is represented by one bit, thus the 8192 bytes will specify access up to 64K. Any zero bit will allow access, while a one will deny access. After the IOPM has been copied to the TSS, the IOPM offset pointer must be adjusted to point to our IOPM. This is done using the Ke386IoSetAccessProcess. The int parameter must be set to 1 to enable it to be set. Calling the function with zero will remove the pointer.