Programación General > ASM (Ensamblador)

 Problema Tonto En Ring 0

<< < (2/3) > >>

Eternal Idol:
Lo que querias hacer ya se habia entendido, sino queres mostrar lo que estas haciendo exactamente no hay problema pero no esperes que te ayude.

G.Owl:
Perdon, creia que no se me entendia.

Aqui pongo el code y digo donde me falla:
Gracias por la ayuda


--- Código: Text --- .386p.model flat,stdcalloption casemap :none include windows.inc include user32.incinclude kernel32.incinclude advapi32.inc includelib user32.libincludelib kernel32.libincludelib advapi32.lib ;*********************************************************************************************; Includes Extra;********************************************************************************************* include ntdll.inc                                                             includelib ntdll.lib  ;_____________________________________________________________________________________________ ;   Variables;_____________________________________________________________________________________________  .data d1 db 'Hola desde Ring0',0 .data?     align dword         dacl            dd      ?        nexp            dd      ?         hPhysicMem      dd      ?         pSecuDescript   dd      ?         pOldDacl        dd      ?        pNewDacl        dd      ?         unicode_str     dw      ?               &#59;UNICODE_STRING{    USHORT          Length                        dw      ?               &#59;                   USHORT          MaxLength                        dd      ?               &#59;                   PWSTR           Buffer };         obj_attrib      dd      ?               &#59;OBJECT_ATTRIBUTES{ ULONG           Length                        dd      ?               &#59;                   HANDLE          RootDirectory                        dd      ?               &#59;                   UNICODE_STRING* ObjectName                        dd      ?               &#59;                   ULONG           Attributes                        dd      ?               &#59;                   VOID*           SecurityDescriptor                        dd      ?               &#59;                   VOID*           SecurityQualityOfService };         Exp_Access      dd      ?               &#59;EXPLICIT_ACCESS{   DWORD           grfAccessPermissions                        dd      ?               &#59;                   ACCESS_MODE     grfAccessMode                        dd      ?               &#59;                   DWORD           grfInheritance                                                &#59;                   TRUSTEE         Trustee };                         dd      ?               &#59;TRUSTEE{           TRUSTEE*        pMultipleTrustee                        dd      ?               &#59;                   MULTIPLE_TRUSTEE_OPERATION MultipleTrusteeOperation                        dd      ?               &#59;                   TRUSTEE_FORM    TrusteeForm                        dd      ?               &#59;                   TRUSTEE_TYPE    TrusteeType                        dd      ?               &#59;                   LPSTR           ptstrName };         gdt             dw      ?               &#59;KGDTENTRY{         WORD            LimitLow                        dw      ?               &#59;                   WORD            BaseLow                        dw      ?               &#59;                   WORD            BaseHigh };         pad1            dw      ?         pAddrgdt        dq      ?               &#59;PHYSICAL_ADDRESS         Callgate        dq      ?               &#59;                  PHYSICAL_ADDRESS pAddress                        dd      ?               &#59;                   VOID*           MappedAddress                        dd      ?               &#59;                   CALLGATE_DESC*  pDesc                        dw      ?               &#59;                   WORD            Segment                        dw      ?               &#59;                   WORD            LastEntry         ViewSize        dd      ?         CgCall          df      ?         pad2            dw      ?         udevname        db      62 dup(?)        buff db ?hout dd ?hin dd ? .const         modname         db      &#34;Ring0&#34;,0         err1            db      &#34;error&#34;,0        err2            db      &#34;error : Acceso Denegado&#34;,0         devname         db      &#34;&#092;device&#092;physicalmemory&#34;,0         user            db      &#34;CURRENT_USER&#34;,0            ;_____________________________________________________________________________________________.code Start:;_____________________________________________________________________________________________    &#59;push 30             invoke      MultiByteToWideChar,CP_ACP,MB_PRECOMPOSED,addr devname,-1,addr udevname,30         .IF eax == 0            invoke      MessageBox,NULL,addr err1,addr modname,MB_OK            jmp         fin        .ENDIF          invoke      RtlInitUnicodeString,addr unicode_str,addr udevname         mov         ebx,offset obj_attrib        mov         dword ptr [ebx],24                                  &#59; sizeof de (OBJECT_ATTRIBUTES)        mov         dword ptr [ebx+4],NULL        mov         dword ptr [ebx+8],offset unicode_str        mov         dword ptr [ebx+12],OBJ_CASE_INSENSITIVE        or          dword ptr [ebx+12],OBJ_KERNEL_HANDLE        mov         dword ptr [ebx+16],NULL        mov         dword ptr [ebx+2],NULL         mov         edx,SECTION_MAP_READ        or          edx,SECTION_MAP_WRITE        invoke      NtOpenSection,addr hPhysicMem,edx,ebx         .IF eax != ERROR_SUCCESS            .IF eax == 0C000022h                jmp         needrw            .ELSE                            invoke      MessageBox,NULL,addr err1,addr modname,MB_OK                jmp         fin            .ENDIF        .ELSE            mov         pOldDacl,NULL            jmp     rw        .ENDIF needrw: mov         edx,WRITE_DAC        or          edx,READ_CONTROL        invoke      NtOpenSection,addr hPhysicMem,edx,addr obj_attrib         .IF eax != ERROR_SUCCESS            .IF eax == 0C0000022h                invoke      MessageBox,NULL,addr err2,addr modname,MB_OK                jmp         fin            .ELSE                            invoke      MessageBox,NULL,addr err1,addr modname,MB_OK                jmp         fin            .ENDIF        .ENDIF          invoke      GetSecurityInfo,hPhysicMem,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,addr pOldDacl,NULL,addr pSecuDescript         .IF eax != ERROR_SUCCESS            invoke      MessageBox,NULL,addr err1,addr modname,MB_OK            jmp         fin        .ENDIF        &#59;invoke      GetExplicitEntriesFromAcl,pOldDacl,addr nexp,addr dacl       &#59;mov         edx,dacl      &#59;mov         edx,[edx+32]      &#59;and         edx,2      &#59;cmp         edx,2      &#59;je          noneed          mov         ebx,offset Exp_Access        mov         dword ptr [ebx],SECTION_ALL_ACCESS        mov         dword ptr [ebx+4],GRANT_ACCESS        mov         dword ptr [ebx+8],NO_INHERITANCE        mov         dword ptr [ebx+12],NULL        mov         dword ptr [ebx+16],NO_MULTIPLE_TRUSTEE        mov         dword ptr [ebx+2],TRUSTEE_IS_NAME        mov         dword ptr [ebx+24],TRUSTEE_IS_USER        mov         dword ptr [ebx+28],offset user         invoke      SetEntriesInAcl,1,addr Exp_Access,pOldDacl,addr pNewDacl         .IF eax != ERROR_SUCCESS            invoke      MessageBox,NULL,addr err1,addr modname,MB_OK            jmp         fin        .ENDIF          invoke      SetSecurityInfo,hPhysicMem,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,pNewDacl,NULL         .IF eax != ERROR_SUCCESS            invoke      MessageBox,NULL,addr err1,addr modname,MB_OK            jmp         fin        .ENDIF          invoke      LocalFree,pNewDaclnoneed: invoke      LocalFree,dacl        invoke      LocalFree,pSecuDescript        invoke      NtClose,hPhysicMem        mov         hPhysicMem,NULL ;______________________________________________________________________________________________________________________;;   Instalacion de la CallGate;______________________________________________________________________________________________________________________          mov         edx,SECTION_MAP_READ        or          edx,SECTION_MAP_WRITE        invoke      NtOpenSection,addr hPhysicMem,edx,addr obj_attrib         .IF eax != ERROR_SUCCESS            .IF eax == 0C0000022h                invoke      MessageBox,NULL,addr err2,addr modname,MB_OK                jmp         fin            .ELSE                            invoke      MessageBox,NULL,addr err1,addr modname,MB_OK                jmp         fin            .ENDIF        .ENDIF  rw:     sgdt        gdt        mov         ebx,offset gdt        movzx       eax,word ptr [ebx+2]        movzx       edx,word ptr [ebx+4]        shl         edx,16        or          edx,eax         .IF (edx &#60; 8000000h) || (edx &#62;= 0A0000000h)            and         edx,0FFFF000h        .ELSE            and         edx,1FFFF000h        .ENDIF         mov         ebx,offset pAddrgdt                 mov         dword ptr [ebx],edx        mov         dword ptr [ebx+4],0        mov         dword ptr [ebx+8],edx        mov         dword ptr [ebx+12],0         push        PAGE_READWRITE        push        0        push        1        movzx       edx,word ptr gdt        mov         ViewSize,edx        push        offset ViewSize        mov         eax,offset Callgate        push        eax        push        edx        push        0        add         eax,8        push        eax        push        -1        push        hPhysicMem        call        NtMapViewOfSection         .IF eax != ERROR_SUCCESS            invoke      MessageBox,NULL,addr err1,addr modname,MB_OK            jmp         fin        .ENDIF          mov         ebx,offset Callgate        mov         dx,word ptr gdt        and         dx,0FFF8h        mov         word ptr [ebx+18],dx        mov         dword ptr [ebx+12],NULL        movzx       eax,dx        mov         ecx,[ebx+8]        add         eax,ecx         .WHILE eax &#62; ecx                                              &#59; Busca un descriptor libre para la callgate en la gdt            mov         dl,byte ptr [eax+5]                           &#59; Mira si el bit 'ocupado' esta a 0. Si esta a 1            and         dl,80h                                        &#59; , esta ocupada la posicion            jne         @f                                            &#59; y se busca en otro sitio.             mov         edx,Ring0            mov         word ptr [eax],dx                             &#59; inicio de la direccion de la funcion de ring 0            mov         word ptr [eax+2],KGDT_R0_CODE            mov         byte ptr [eax+4],1                            &#59; Le paso 1 parametro                                                                      &#59; El nº de parametro esta codificado                                                                      &#59; en los 4 primeros bits del byte, no se pueden pasar mas de 15                                                                      &#59; sino me pasaria de bytes            mov         byte ptr [eax+5],0ECh            shr         edx,16            mov         word ptr [eax+6],dx                           &#59; final de la direccion de la funcion de ring0            mov         dword ptr [ebx+12],eax            jmp         fwh @@:         sub         eax,8                   &#59; le paso un parametro porque me gustaria llamar        .ENDW                                                         &#59; a GetModuleHandle desde dentro de la funncion                                                                      &#59;ring 0fwh:    mov         edx,[ebx+12]         .IF edx == NULL                                               &#59; Encuentro un descriptor libre ? Sino paro.            invoke      MessageBox,NULL,addr err1,addr modname,MB_OK            jmp         fin        .ENDIF          mov         edx,eax        sub         edx,[ebx+8]        or          dx,3        mov         word ptr [ebx+16],dx ;______________________________________________________________________________________________________________________;;   Llamada de la función Ring0;______________________________________________________________________________________________________________________          mov         eax,offset CgCall        mov         dx,word ptr [ebx+16]        mov         word ptr [eax+4],dx        mov         dword ptr [eax],0         push        thend-Ring0        push        Ring0        call        VirtualLock         call        GetCurrentThread        invoke      SetThreadPriority,eax,THREAD_PRIORITY_TIME_CRITICAL         invoke      Sleep,0                                          push        fs                                                                                                                                                                                                                 pop         fs         call        GetCurrentThread        invoke      SetThreadPriority,eax,THREAD_PRIORITY_NORMAL         push        thend-Ring0        push        Ring0        call        VirtualUnlock ;______________________________________________________________________________________________________________________;;   Limpieza y desinstalacion de la CallGate;______________________________________________________________________________________________________________________          mov         ebx,offset Callgate        mov         edi,[ebx+12]        xor         eax,eax        stosd        stosd         .IF pOldDacl != NULL            invoke      SetSecurityInfo,hPhysicMem,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,pOldDacl,NULL        .ENDIF         invoke      NtUnmapViewOfSection,-1,dword ptr [ebx+8]        invoke      NtClose,hPhysicMem ;______________________________________________________________________________________________________________________  fin:    invoke      ExitProcess,0 ;______________________________________________________________________________________________________________________  ;______________________________________________________________________________________________________________________;;   La funcion que va a &#34;saltar&#34; a modo kernel;   no hace nada, pero cuidado que el sistema puede caerse al mas minimo error;   me dieron algunos pantallazos al programar esto...;______________________________________________________________________________________________________________________  Ring0 PROC         pushad                                        &#59; Guardo los registros y flags        pushf                                                    mov         ebp,esp                           &#59; para restaurar mas tarde la pila                                                      &#59;          mov         eax,[ebp+42]                      &#59; recupero los parametros en eax                                                       &#59; durante un call, se pushea la direccion de retorno cuando                                                      &#59; es una llamada far, la direccion de retorno incluye CS                                                     &#59; asi que son 8 bytes de la pila (en realidad son 6 bytes)                                                                                                        &#59; Al cambiar de privilegios se pushea :                                                      &#59; ss y esp de la pila de ring 3, la configuracion y entonces cs eip.                                                      &#59; Al entrar al procedimiento el primer parametro                                                      &#59; esta en [esp+8], entonces se calcula lo que se pusheo                                                      &#59; hace tiempo pushad (32), pushf (2) + esp                                                      &#59; 32 + 2+ 8 = 42    &#59; Aqui Cli y Sti funciona pero este code de debajo no y no se el por que. &#59; No me deja llamara ninguna api   push STD_OUTPUT_HANDLE   call GetStdHandle; obtendre el handle de la consola  mov  edi,eax   &#59; copio a hout el handle obtenido    push NULL; nulo      lea eax,buff; buffer de escritura      push eax; meto el buffer en la pila      push 17;longitud del mensaje      lea eax,d1      push eax; meto la cadena en la pila      push edi;meto en la pila el handle      call WriteConsole                   popf                                          &#59; restauro los flags        popad        retf 4                                        &#59; ajusto la pila Ring0 ENDP thend:                  &#59; etiqueta para facilitar el calculo del tamaño de la funcion ;______________________________________________________________________________________________________________________   end   Start  

Eternal Idol:
Me traiciono la memoria evidentemente, hubiera jurado que PhysicaMemory estaba vedado en XP pero veo que es de 2003 Server en adelante.

Al codigo le faltaba la parte en la cual llamaba a la funcion aunque la encontre rapidamente en  Internet.

¿Cual es la razon por la cual pensas que tiene algun sentido llamar a una funcion de modo Usuario desde modo Kernel? La amplia mayoria de ellas intentan pasar a modo Kernel justamente. GetStdHandle es una excepcion ya que usa el PEB (RTL_USER_PROCESS_PARAMETERS) para devolver esos valores.

En fin, si se comporta tal como en mi maquina virtual la excepcion se produce por una razon muy simple, esa funcion no esta en memoria y el Kernel se encarga de manejar el page-fault (si lo depuraras verias como justo despues de la ejecucion de MmAccessFault si esta disponible el codigo de la funcion en memoria)  :D Si llamaras a WriteConsoleA antes no daria una excepcion aunque seguiria siendo inutil por supuesto. En modo Kernel hay que usar las funciones ofrecidas por el Kernel y no por la API de Windows de modo Usuario.

G.Owl:
mm El WinDbg es feo. Me baje incluso una interfaz para él pero sigo sin conocerlo muy bien todavia.

La razon de llamar apis de modo usuario ? Pues porque si hay apis en modo kernel que hacen lo mismo no se cuales son.

Tengo un pdf de la api nativa de Windows Xp pero si existen las apis equivalentes no se cuales son. No creas que no las estoy buscando.

Si consiguiera cargar la libreria kernel32.dll en modo kernel podria acceder a sus apis ?
Hay alguna forma de hacer esto ?
Es que tenia entendido que en modo kernel tienes acceso a todas las direcciones.

Gracias

Eternal Idol:
El WinDbg permite depurar en modo Usuario y modo Kernel, el OllyDbg no asi que no hay punto de comparacion.

¿Y cual es la razon para hacer en modo Kernel lo que en modo Usuario? No tiene sentido ...

La API nativa de XP es la NTDLL.dll - una libreria dinamica comun y corriente de modo Usuario - que en su mayoria de funciones solo transforma unos parametros y pasa a modo Kernel.


La DLL - Kernel32 - ya esta cargada en tu proceso y GetStdHandle es ejecutada correctamente, si llamaras antes desde modo Usuario a esa funcion - WriteConsoleA - como te dije no daria una excepcion al no tener que resolver el page-fault el Kernel - cuando lo hace vuelve a modo Usuario -.

En modo Kernel hay que usar las funciones ofrecidas por el Kernel y no por la API de Windows de modo Usuario.

Navegación

[0] Índice de Mensajes

[#] Página Siguiente

[*] Página Anterior

Ir a la versión completa