News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

API NetShareEnum

Started by Fraile, February 02, 2024, 11:51:55 PM

Previous topic - Next topic

jj2007

Quote from: Fraile on February 07, 2024, 01:53:18 AMHere is the ASM code of the project

Little problems
Tmp_File.asm(57) : Error A2160: INVOKE requires prototype for procedure
Tmp_File.asm(61) : Error A2160: INVOKE requires prototype for procedure
Tmp_File.asm(65) : Error A2160: INVOKE requires prototype for procedure
Tmp_File.asm(66) : Error A2160: INVOKE requires prototype for procedure
Tmp_File.asm(72) : Error A2275: Constant value too large: 6E657461706933322E646C6Ch
Tmp_File.asm(72) : Error A2147: Too few arguments to INVOKE: LoadLibraryA
Tmp_File.asm(79) : Error A2275: Constant value too large: 4E65745368617265456E756Dh
Tmp_File.asm(79) : Error A2147: Too few arguments to INVOKE: GetProcAddress

Fraile

Hello jj2007, as I mentioned, I use EASY CODE by Ramon Salas as my IDLE, and I compile with MASM32. This could potentially be a problem; if you notice, the libraries don't appear in the code because I add them directly to the IDLE. Here's the URL for the IDLE: https://easycode.cat/Spanish/index.htm

Fraile

Last code:

AsigText Macro Name, Text:VarArg
    Local lbl
    Jmp lbl
        Name DB Text, 0
lbl:

EndM

.Const

bufferSize Equ 256

.Data?

.Data


   
    hInst        HINSTANCE    NULL

    level          DD 1                  ; Nivel de detalle para la enumeración
    buf            DD 0                  ; Puntero al buffer de salida
    entriesRead    dd 0                  ; Número de entradas leídas
    totalEntries    DD 0                  ; Número total de entradas
    TotalBuffer        DD 0                  ; Total de bytes para reservar el buffer.

    tempbuffer      DB 10 Dup(NULL)      ; Buffer temporal para la rutina de paso a numeros decimales.
    HandleConsola    DD 0
    CarroDeRetorno  DB 13 ; Código ASCII para retorno de carro
    NuevaLinea      DB 10 ; Código ASCII para nueva línea

    serverName      DW bufferSize Dup(?)
    resumeHandle    DD 0  ; Handle de NetShareEnum de sonda para el calculo del buffer.
    format          DB 'Argumentos %d = %s', 13, 10, 0
    buffer          DB 256 Dup(?)
    TamanoNameRecurso DD 0
    shi1_netnameAux DW 20 Dup(' '), 0

    fmtAccessDeniedError    DB "Error de acceso denegado.", 0
    fmtNotEnoughMemoryError db "Error: No hay suficiente memoria disponible.", 0



.Code

start:
    Invoke GetModuleHandle, NULL
    Mov hInst, Eax

    ; Obtener el identificador de la consola estándar
    Invoke GetStdHandle, STD_OUTPUT_HANDLE
    Mov HandleConsola, Eax  ; edx ahora contiene el identificador de la consola

    ;=====================

    AsigText Cabecera0, "----------------------------------"
    Invoke WriteConsoleA, HandleConsola, Addr Cabecera0, 34, 0, 0
    Invoke ImprimirSaltoDeLinea

    AsigText Cabecera1, "FraiSMBShareEnum by Fraile - 2024."
    Invoke WriteConsoleA, HandleConsola, Addr Cabecera1, 34, 0, 0
    Invoke ImprimirSaltoDeLinea

    AsigText Cabecera2, "----------------------------------"
    Invoke WriteConsoleA, HandleConsola, Addr Cabecera2, 34, 0, 0
    Invoke ImprimirSaltoDeLinea
    Invoke ImprimirSaltoDeLinea


  ; Cargar la biblioteca dinámica wnetapi32.dll
  Invoke LoadLibrary, TextStr("netapi32.dll")

  .If Eax

        Mov Edi, Eax


        ; Obtenemos los bytes del buffer que tenemos que crear para recoger la informacion.

        ; Obtener el puntero a la función NetShareEnum
        Invoke GetProcAddress, Edi, TextStr("NetShareEnum")
        Mov Esi, Eax

        Push Esi
        Push Edi
        Invoke ArmarArgumentos
        Pop Edi
        Pop Esi

        ;Invoke NetShareEnum, NULL, 1, 0, NULL, MAX_PREFERRED_LENGTH, Addr entriesRead, Addr totalEntries, Addr resumeHandle

        Push 0
        Lea Eax, totalEntries
        Push Eax
        Lea Eax, entriesRead
        Push Eax
        Mov Eax, MAX_PREFERRED_LENGTH
        Push Eax
        Lea Eax, buf
        Push Eax
        Push level
        Lea Eax, serverName
        Push Eax

        Call Esi

        Test Eax, Eax
          Jnz handle_error

        ; Calcula el tamaño del búfer necesario
        Mov Eax, totalEntries  ; Obtiene el número total de entradas
        IMul Eax, SizeOf SHARE_INFO_1  ; Multiplica por el tamaño de cada entrada
        Add Eax, 4  ; Añade 4 bytes adicionales para compensar posibles alineaciones

        Mov TotalBuffer, Eax


        ; Obtener el puntero a la función NetShareEnum
        Invoke GetProcAddress, Edi, TextStr("NetShareEnum")

        .If Eax

            Mov Esi, Eax

            ; Calcular el tamaño del buffer necesario
            ; Reservar memoria para el buffer
            Invoke GlobalAlloc, GMEM_ZEROINIT, TotalBuffer ; Puedes ajustar el tamaño del buffer según tus necesidades
            Mov buf, Eax


            Push 0
            Lea Eax, totalEntries
            Push Eax
            Lea Eax, entriesRead
            Push Eax
            Mov Eax, MAX_PREFERRED_LENGTH
            Push Eax
            Lea Eax, buf
            Push Eax
            Push level
            Lea Eax, serverName
            Push Eax

            Call Esi

            Test Eax, Eax
            Jnz handle_error

            ; Mostramos el numero de recursos detectados.
            Invoke ImprimirSaltoDeLinea
            AsigText Cabecera3, "Total de recursos detectados: "
            Invoke WriteConsoleA, HandleConsola, Addr Cabecera3, 30, 0, 0
            Invoke PasarADecimal, totalEntries
            Invoke WriteConsoleA, HandleConsola, Addr tempbuffer, 4, 0, 0
            Invoke ImprimirSaltoDeLinea
            Invoke ImprimirSaltoDeLinea

            AsigText Cabecera4, "Nombre Recurso        Tipo                      Comentario"
            Invoke WriteConsoleA, HandleConsola, Addr Cabecera4, 58, 0, 0
            Invoke ImprimirSaltoDeLinea

            AsigText Cabecera5, "----------------------------------------------------------"
            Invoke WriteConsoleA, HandleConsola, Addr Cabecera5, 58, 0, 0
            Invoke ImprimirSaltoDeLinea


            ; Pintar los recursos compartidos.
            ; ********************************

          Mov Esi, buf ; esi apunta al búfer de datos
          Mov Ecx, entriesRead ; Número de recursos compartidos
          Dec Ecx
         
          ; Bucle para leer y procesar cada estructura SHARE_INFO_1 en el búfer
          .repeat
            ; Acceder a los miembros de la estructura SHARE_INFO_1
            Mov Edx, [Esi].SHARE_INFO_1.shi1_netname ; Nombre del recurso compartido (Unicode)
            ; Aquí puedes hacer lo que necesites con la información
            Lea Ebx, [Edx]
            Push Ebx
            Invoke UniStrLen, Ebx
            Mov TamanoNameRecurso, Eax
            Pop Ebx

            ; Ajustamos el nombre del recurso a 20 caracteres.

            .If TamanoNameRecurso < 20

                Push Ecx

                Mov Eax, 20
                Mov Edx, TamanoNameRecurso

                Sub Eax, Edx

                Push Ebx
                Push Eax

                ; Limpiar el buffer
                Mov Edi, Offset shi1_netnameAux    ; Puntero al inicio del buffer
                Mov Ecx, LengthOf shi1_netnameAux  ; Longitud del buffer (número de elementos)
                Mov Ax, ' '  ; Valor a escribir en el buffer (0 para limpiar)
                Rep Stosw  ; Llena el buffer con el valor en ax ''

                Pop Eax
                Pop Ebx

                Invoke lstrcpynW, Addr shi1_netnameAux, Ebx, TamanoNameRecurso + 1

                Pop Ecx

            .EndIf


            Invoke WriteConsoleW, HandleConsola, Addr shi1_netnameAux, 20, 0, 0
   
            ; Tipo de Recurso
            Mov Edx, [Esi].SHARE_INFO_1.shi1_type ; Tipo de recurso.
   
            .If Edx == STYPE_DISKTREE
                AsigText TipoRecurso, "Disco.                  "
                Invoke WriteConsoleA, HandleConsola, Addr TipoRecurso, 25, 0, 0
            .Else
                .If Edx == STYPE_IPC
                    AsigText TipoRecurso1, "IPC.                    "
                    Invoke WriteConsoleA, HandleConsola, Addr TipoRecurso1, 25, 0, 0
                .Else
                    .If Edx == STYPE_DEVICE
                        AsigText TipoRecurso2, "Dispositivo Comunicacion."
                        Invoke WriteConsoleA, HandleConsola, Addr TipoRecurso2, 25, 0, 0
                    .Else
                        .If Edx == STYPE_PRINTQ
                            AsigText TipoRecurso3, "Impresora.              "
                            Invoke WriteConsoleA, HandleConsola, Addr TipoRecurso3, 25, 0, 0
                        .Else
                            .If Edx == STYPE_SPECIAL
                                AsigText TipoRecurso4, "Especial.                "
                                Invoke WriteConsoleA, HandleConsola, Addr TipoRecurso4, 25, 0, 0
                            .Else
                                AsigText TipoRecurso5, "No Identificado.        "
                                Invoke WriteConsoleA, HandleConsola, Addr TipoRecurso5, 25, 0, 0
                            .EndIf
                        .EndIf
                    .EndIf
   
                .EndIf
            .EndIf
   
            ; Comentario.
            AsigText Comentario, " -> "
              Invoke WriteConsoleA, HandleConsola, Addr Comentario, 4, 0, 0
   
            Mov Edx, [Esi].SHARE_INFO_1.shi1_remark ; Comentario.
   
            Lea Ebx, [Edx]
            Push Ebx
            Invoke UniStrLen, Ebx
            Pop Ebx
            Invoke WriteConsoleW, HandleConsola, Ebx, Eax, 0, 0
   
   
            Invoke ImprimirSaltoDeLinea
   
            ; Avanzar al siguiente elemento en la lista
            add esi, SIZEOF SHARE_INFO_1
            Dec Ecx

          .Until Ecx == 0



   
        Invoke GlobalFree, buf

        jmp cleanup



        .EndIf

  .EndIf

handle_error:
    ; Manejo de errores
    cmp eax, ERROR_ACCESS_DENIED
    je access_denied_error
    cmp eax, ERROR_NOT_ENOUGH_MEMORY
    je not_enough_memory_error
    ; Puedes agregar más casos según sea necesario

    ; Otros casos no manejados específicamente
    AsigText Error1, "Error Desconocido."
    Invoke WriteConsoleA, HandleConsola, Addr Error1, SizeOf Error1, 0, 0

    jmp cleanup

access_denied_error:
    ; Código para manejar el error de acceso denegado
    Invoke UniStrLen, Addr fmtAccessDeniedError
    Invoke WriteConsoleW, HandleConsola, Addr fmtAccessDeniedError, Eax, 0, 0
    jmp cleanup

not_enough_memory_error:
    ; Código para manejar el error de falta de memoria
    Invoke UniStrLen, Addr fmtNotEnoughMemoryError
    Invoke WriteConsoleW, HandleConsola, Addr fmtNotEnoughMemoryError, Eax, 0, 0
    jmp cleanup

cleanup:
    Invoke ExitProcess, 0

; Función para obtener una cadena de error a partir de un código de error
GetLastErrorString proc errorCode:DWORD, lpBuffer:PTR WCHAR
    invoke FormatMessageW, FORMAT_MESSAGE_FROM_SYSTEM, 0, errorCode, 0, lpBuffer, 512, 0
    ret
GetLastErrorString endp


; Función para obtener la longitud de una cadena Unicode
UniStrLen PROC _string:DWORD

    mov    eax,_string
    mov    ecx,4
    sub    eax,ecx
@@:
    add    eax,ecx
    mov    edx,DWORD PTR [eax]
    test    dx,dx
    je      @f
    test    edx,0FFFF0000h
    jnz    @b
    add    eax,2
@@: 
    sub    eax,_string
    shr    eax,1
    ret

UniStrLen EndP
ImprimirSaltoDeLinea proc
    ; Imprime un retorno de carro (CR) y una nueva línea (LF) en la consola
    Invoke WriteConsole, HandleConsola, Addr CarroDeRetorno, 1, 0, 0
    Invoke WriteConsole, HandleConsola, Addr NuevaLinea, 1, 0, 0
    ret
ImprimirSaltoDeLinea EndP
PasarADecimal Proc Valor:DWord
        Push Esi
        Push Edi

        Mov Esi, Valor
        Mov Edi, Offset tempbuffer
        Invoke dwtoa, Esi, Edi

        Pop Edi
        Pop Esi

        Ret

PasarADecimal EndP
ArmarArgumentos Proc

LOCAL argc:DWORD

    invoke  GetCommandLineW
    lea    ecx,argc
    invoke  CommandLineToArgvW,eax,ecx

    Mov Esi, Eax
    Add Esi, 4
    mov    ebx,argc
    Xor Edi, Edi

    Push Edi
    Push Esi


    ; Esi apunta al segundo argumento en formato Unicode
    Mov Esi, [Esi]
   
    ; Copiar el segundo argumento a ipbuffer
    Invoke lstrcpynW, Addr serverName, Esi, 256

    Pop Esi
    Pop Edi


;@@:
    Inc Edi
;
;; Convert UNICODE string to ANSI
;
    Invoke WideCharToMultiByte, CP_ACP, 0, \
            DWord Ptr [Esi], -1, Addr buffer, \
            256, 0, 0
;         
    Invoke crt_printf, Addr format, Edi, Addr buffer
;    add    esi,4
;    dec    ebx
;    jnz    @b


    Ret
ArmarArgumentos EndP



jj2007

I wonder what these strings mean; this is what I get with a null$:
9 entries found
ADMIN$
Amministrazione remota
C:\Windows
C$
Condivisione predefinita
C:\
Canon MG3600 series HTTP


jj2007

Interesting, thanks Timo, but my Win10 registry keys look different :sad:

TimoVJL

There was explanations for those shares
Administrative share
SMB/Windows Admin Shares
Overview of problems that may occur when administrative shares are missing
>net share

Share name  Resource                        Remark

-----------------------------------------------------------
C$          C:\                            Default share
IPC$                                        Remote IPC
ADMIN$      C:\Windows                      Remote Admin
The command completed successfully.
May the source be with you

jj2007

Quote from: TimoVJL on February 09, 2024, 04:03:30 AMThere was explanations for those shares
Administrative share
SMB/Windows Admin Shares
Overview of problems that may occur when administrative shares are missing

Thanks, Timo, very interesting links indeed :thumbsup:

I rolled my own, see NetShareEnum alias net share; strangely enough, the entries that pop up don't show in the registry. A few can be found, but there is no single place where all of them are registered.