News:

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

Main Menu

COM, create rule in Firewall to windows

Started by Fraile, June 10, 2024, 07:02:55 PM

Previous topic - Next topic

Fraile

Does anyone know how to set the property values in a COM object? In this case, it's for creating a rule in the Windows firewall. I think I have the instances correctly, but I don't know how to load the properties and call the methods. Thank you very much.


.386
.Model Flat, StdCall
Option CaseMap :None
AsigText Macro Name, Text:VarArg
Local lbl
Jmp lbl
Name DB Text, 0
lbl:
EndM
.Const
    GuiPolicy  TextEqu   <{098325047H, 0C671H, 04174H, {08DH, 081H, 0DEH, 0FCH, 0D3H, 0F0H, 031H, 086H}}>
    IID_FwRule TextEqu   <{0AF230D27H, 0BABAH, 04E42H, {0ACH, 0EDH, 0F5H, 024H, 0F2H, 02CH, 0FCH, 0E2H}}>

    NET_FW_ACTION_BLOCK equ 0
    NET_FW_RULE_DIR_IN  Equ 1

.Data?

    pFwPolicy2              DD ?
pFwRule                 DD ?


.Data
    HandleConsola DD 0
    CarroDeRetorno           DB 13 ; Código ASCII para retorno de carro
    NuevaLinea               DB 10 ; Código ASCII para nueva línea

    ProgID_HNetCfg_FwPolicy2 DW 'H', 'N', 'e', 't', 'C', 'f', 'g', '.', 'F', 'w', 'P', 'o', 'l', 'i', 'c', 'y', '2', 0
    ProgID_HNetCfg_Fwrule    DW 'H', 'N', 'e', 't', 'C', 'f', 'g', '.', 'F', 'W', 'R', 'u', 'l', 'e', 0

CLSIDFw                  GUID <>
    IID_INetFwPolicy2        GUID GuiPolicy
    CLSID_NetFwRule          GUID <>
IID_INetFwRule GUID IID_FwRule

    ruleName            DW 'B', 'l', 'o', 'c', 'k', 'S', 'p', 'e', 'c', 'i', 'f', 'i', 'c', 'I', 'P', 0
    ruleDescription     DW 'B', 'l', 'o', 'c', 'k', ' ', 't', 'r', 'a', 'f', 'f', 'i', 'c', ' ', 'f', 'r', 'o', 'm', ' ', 's', 'p', 'e', 'c', 'i', 'f', 'i', 'c', ' ', 'I', 'P', 0
    remoteAddresses     DW '1', '9', '2', '.', '1', '6', '8', '.', '1', '.', '1', 0  ; Cambia esta IP a la que deseas bloquear

;    ruleName            DB "BlockSpecificIP", 0
;    ruleDescription     DB "Block traffic from specific IP", 0
;    remoteAddresses     DB "192.168.1.1", 0  ; Cambia esta IP a la que deseas bloquear


.Code

start:

  Invoke GetStdHandle, STD_OUTPUT_HANDLE
  Mov HandleConsola, Eax

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

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

AsigText Cabecera1, "FraiFRW by Fraile - 2024."
    Invoke WriteConsoleA, HandleConsola, Addr Cabecera1, 25, 0, 0
    Invoke ImprimirSaltoDeLinea

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

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

    ; Initialize COM library
    Invoke CoInitialize, NULL
    Cmp Eax, S_OK
Jne ErrorInicializacionCOM

Invoke CLSIDFromProgID, Addr ProgID_HNetCfg_FwPolicy2, Addr CLSIDFw
Cmp Eax, S_OK
Jne ErrorCLIDIdentifi

    Invoke CoCreateInstance, Addr CLSIDFw, NULL, CLSCTX_LOCAL_SERVER, Addr IID_INetFwPolicy2, Addr pFwPolicy2

    ; Check if the instance was created successfully
    Cmp Eax, S_OK
    Jne ErrorCoCrea

Invoke CLSIDFromProgID, Addr ProgID_HNetCfg_Fwrule, Addr CLSID_NetFwRule
Cmp Eax, S_OK
Jne ErrorCLIDIdentifi

    ; Crear una instancia de la interfaz INetFwRule
    Invoke CoCreateInstance, Addr CLSID_NetFwRule, NULL, CLSCTX_INPROC_SERVER, Addr IID_INetFwRule, Addr pFwRule
    Cmp Eax, S_OK
    Jne ErrorCoCreaRule

.
.
.
.
.




    ; Cerrar la biblioteca COM
    invoke CoUninitialize
    Invoke ExitProcess, 0

ErrorInicializacionCOM:
AsigText Error0, "Error Ini COM."
    Invoke WriteConsoleA, HandleConsola, Addr Error0, 14, 0, 0
    Invoke ImprimirSaltoDeLinea

    Invoke CoUninitialize
    Invoke ExitProcess, 1

ErrorCLIDIdentifi:
AsigText Error1, "Error Identifi Clid."
    Invoke WriteConsoleA, HandleConsola, Addr Error1, 20, 0, 0
    Invoke ImprimirSaltoDeLinea

    Invoke CoUninitialize
    Invoke ExitProcess, 1

ErrorClsID:
AsigText Error2, "Error Clid."
    Invoke WriteConsoleA, HandleConsola, Addr Error2, 11, 0, 0
    Invoke ImprimirSaltoDeLinea

    Invoke CoUninitialize
    Invoke ExitProcess, 1

ErrorCoCrea:
AsigText Error3, "Error al instanciar Obj."
    Invoke WriteConsoleA, HandleConsola, Addr Error3, 25, 0, 0
    Invoke ImprimirSaltoDeLinea

    Invoke CoUninitialize
    Invoke ExitProcess, 1

ErrorCoCreaRule:
AsigText Error4, "Error al instanciar regla."
    Invoke WriteConsoleA, HandleConsola, Addr Error4, 27, 0, 0
    Invoke ImprimirSaltoDeLinea

    Invoke CoUninitialize
    Invoke ExitProcess, 1

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

End start



TimoVJL

Here is C header from FirewallAPI.tlb

Look those get / put methods.
May the source be with you

Fraile

Thank you very much, TimoVJL, but could I use this with masm32? Or is it just for reference on accessing methods, properties, etc.? Do you have any examples in masm32?

TimoVJL

#3
I don't use assembler these days.
It was just for our COM specialist.
coinvoke macro helps with COM objects.
In this site are many members, who can help you with COM code.
May the source be with you

Fraile


Fraile

With firewall.h, I obtain the methods. According to what I have read, I can refer to them through offsets.

   /* INetFwRule methods */
   HRESULT (STDMETHODCALLTYPE *get_Name)(INetFwRule *This,BSTR*);
   HRESULT (STDMETHODCALLTYPE *put_Name)(INetFwRule *This,BSTR);
   HRESULT (STDMETHODCALLTYPE *get_Description)(INetFwRule *This,BSTR*);
   HRESULT (STDMETHODCALLTYPE *put_Description)(INetFwRule *This,BSTR);
   HRESULT (STDMETHODCALLTYPE *get_ApplicationName)(INetFwRule *This,BSTR*);
   HRESULT (STDMETHODCALLTYPE *put_ApplicationName)(INetFwRule *This,BSTR);
   HRESULT (STDMETHODCALLTYPE *get_serviceName)(INetFwRule *This,BSTR*);
   HRESULT (STDMETHODCALLTYPE *put_serviceName)(INetFwRule *This,BSTR);
   HRESULT (STDMETHODCALLTYPE *get_Protocol)(INetFwRule *This,LONG*);
   HRESULT (STDMETHODCALLTYPE *put_Protocol)(INetFwRule *This,LONG);
   HRESULT (STDMETHODCALLTYPE *get_LocalPorts)(INetFwRule *This,BSTR*);
   HRESULT (STDMETHODCALLTYPE *put_LocalPorts)(INetFwRule *This,BSTR);
   HRESULT (STDMETHODCALLTYPE *get_RemotePorts)(INetFwRule *This,BSTR*);
   HRESULT (STDMETHODCALLTYPE *put_RemotePorts)(INetFwRule *This,BSTR);
   HRESULT (STDMETHODCALLTYPE *get_LocalAddresses)(INetFwRule *This,BSTR*);
   HRESULT (STDMETHODCALLTYPE *put_LocalAddresses)(INetFwRule *This,BSTR);
   HRESULT (STDMETHODCALLTYPE *get_RemoteAddresses)(INetFwRule *This,BSTR*);
   HRESULT (STDMETHODCALLTYPE *put_RemoteAddresses)(INetFwRule *This,BSTR);
   HRESULT (STDMETHODCALLTYPE *get_IcmpTypesAndCodes)(INetFwRule *This,BSTR*);
   HRESULT (STDMETHODCALLTYPE *put_IcmpTypesAndCodes)(INetFwRule *This,BSTR);
   HRESULT (STDMETHODCALLTYPE *get_Direction)(INetFwRule *This,enum NET_FW_RULE_DIRECTION_*);
   HRESULT (STDMETHODCALLTYPE *put_Direction)(INetFwRule *This,enum NET_FW_RULE_DIRECTION_);
   HRESULT (STDMETHODCALLTYPE *get_Interfaces)(INetFwRule *This,VARIANT*);
   HRESULT (STDMETHODCALLTYPE *put_Interfaces)(INetFwRule *This,VARIANT);
   HRESULT (STDMETHODCALLTYPE *get_InterfaceTypes)(INetFwRule *This,BSTR*);
   HRESULT (STDMETHODCALLTYPE *put_InterfaceTypes)(INetFwRule *This,BSTR);
   HRESULT (STDMETHODCALLTYPE *get_Enabled)(INetFwRule *This,VARIANT_BOOL*);
   HRESULT (STDMETHODCALLTYPE *put_Enabled)(INetFwRule *This,VARIANT_BOOL);
   HRESULT (STDMETHODCALLTYPE *get_Grouping)(INetFwRule *This,BSTR*);
   HRESULT (STDMETHODCALLTYPE *put_Grouping)(INetFwRule *This,BSTR);
   HRESULT (STDMETHODCALLTYPE *get_Profiles)(INetFwRule *This,LONG*);
   HRESULT (STDMETHODCALLTYPE *put_Profiles)(INetFwRule *This,LONG);
   HRESULT (STDMETHODCALLTYPE *get_EdgeTraversal)(INetFwRule *This,VARIANT_BOOL*);
   HRESULT (STDMETHODCALLTYPE *put_EdgeTraversal)(INetFwRule *This,VARIANT_BOOL);
   HRESULT (STDMETHODCALLTYPE *get_Action)(INetFwRule *This,enum NET_FW_ACTION_*);
   HRESULT (STDMETHODCALLTYPE *put_Action)(INetFwRule *This,enum NET_FW_ACTION_);

If I want to load a value into the put_name property, I need to find its offset. From what I have seen, this is calculated by enumerating each of the previously mentioned properties and multiplying by 4 if it's a 32-bit application or by 8 if it's a 64-bit application. In my case, I am developing the application with MASM32, so I multiply by 4.

get_Name - index 0
put_Name - index 1 (offset 1 * 4 = 4 bytes or 0x04)
get_Description - index 2
put_Description - index 3 (offset 3 * 4 = 12 bytes or 0x0C)



Fraile

Alright, so now to assign values to the COM object and add a new rule, I can load them as follows:


.386
.Model Flat, StdCall
Option CaseMap :None
AsigText Macro Name, Text:VarArg
Local lbl
Jmp lbl
Name DB Text, 0
lbl:
EndM
.Const
    GuiPolicy  TextEqu   <{098325047H, 0C671H, 04174H, {08DH, 081H, 0DEH, 0FCH, 0D3H, 0F0H, 031H, 086H}}>
    IID_FwRule TextEqu   <{0AF230D27H, 0BABAH, 04E42H, {0ACH, 0EDH, 0F5H, 024H, 0F2H, 02CH, 0FCH, 0E2H}}>



    NET_FW_ACTION_BLOCK Equ 0
    NET_FW_RULE_DIR_IN  Equ 1

.Data?

    pFwPolicy2              DD ?
pFwRule                 DD ?

    bstrName                DD ?
    bstrDescription         DD ?
    bstrRemoteAddresses     DD ?


.Data
    HandleConsola DD 0
    CarroDeRetorno           DB 13 ; Código ASCII para retorno de carro
    NuevaLinea               DB 10 ; Código ASCII para nueva línea

    ProgID_HNetCfg_FwPolicy2 DW 'H', 'N', 'e', 't', 'C', 'f', 'g', '.', 'F', 'w', 'P', 'o', 'l', 'i', 'c', 'y', '2', 0
    ProgID_HNetCfg_Fwrule    DW 'H', 'N', 'e', 't', 'C', 'f', 'g', '.', 'F', 'W', 'R', 'u', 'l', 'e', 0

CLSIDFw                  GUID <>
    IID_INetFwPolicy2        GUID GuiPolicy
    CLSID_NetFwRule          GUID <>
IID_INetFwRule GUID IID_FwRule

    ruleName            DW 'B', 'l', 'o', 'c', 'k', 'S', 'p', 'e', 'c', 'i', 'f', 'i', 'c', 'I', 'P', 0
    ruleDescription     DW 'B', 'l', 'o', 'c', 'k', ' ', 't', 'r', 'a', 'f', 'f', 'i', 'c', ' ', 'f', 'r', 'o', 'm', ' ', 's', 'p', 'e', 'c', 'i', 'f', 'i', 'c', ' ', 'I', 'P', 0
    remoteAddresses     DW '1', '9', '2', '.', '1', '6', '8', '.', '1', '.', '1', 0  ; Cambia esta IP a la que deseas bloquear


.Code

start:

  Invoke GetStdHandle, STD_OUTPUT_HANDLE
  Mov HandleConsola, Eax

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

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

AsigText Cabecera1, "FraiFRW by Fraile - 2024."
    Invoke WriteConsoleA, HandleConsola, Addr Cabecera1, 25, 0, 0
    Invoke ImprimirSaltoDeLinea

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

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

    ; Initialize COM library
    Invoke CoInitialize, NULL
    Cmp Eax, S_OK
Jne ErrorInicializacionCOM

Invoke CLSIDFromProgID, Addr ProgID_HNetCfg_FwPolicy2, Addr CLSIDFw
Cmp Eax, S_OK
Jne ErrorCLIDIdentifi

    Invoke CoCreateInstance, Addr CLSIDFw, NULL, CLSCTX_LOCAL_SERVER, Addr IID_INetFwPolicy2, Addr pFwPolicy2

    ; Check if the instance was created successfully
    Cmp Eax, S_OK
    Jne ErrorCoCrea

Invoke CLSIDFromProgID, Addr ProgID_HNetCfg_Fwrule, Addr CLSID_NetFwRule
Cmp Eax, S_OK
Jne ErrorCLIDIdentifi

    ; Crear una instancia de la interfaz INetFwRule
    Invoke CoCreateInstance, Addr CLSID_NetFwRule, NULL, CLSCTX_INPROC_SERVER, Addr IID_INetFwRule, Addr pFwRule
    Cmp Eax, S_OK
    Jne ErrorCoCreaRule


    ; Establecer las propiedades de la regla
    Invoke SysAllocString, Addr ruleName
    Mov bstrName, Eax
    Cmp Eax, 0
    Je ErrorSysAlloc
    Mov Eax, pFwRule
    Mov Edx, [Eax]
    Push bstrName
    Call DWord Ptr [Edx + 04H]   ; Offset para put_Name
    Invoke SysFreeString, bstrName

    Invoke SysAllocString, Addr ruleDescription
    Mov bstrDescription, Eax
    Cmp Eax, 0
    Je ErrorSysAlloc
    Mov Eax, pFwRule
    Mov Edx, [Eax]
    Push bstrDescription
    Call DWord Ptr [Edx + 0CH]   ; Offset para put_Description
    Invoke SysFreeString, bstrDescription

    ; Mensaje de éxito
    AsigText ReglaCreada, "Regla Creada!."
    Invoke WriteConsoleA, HandleConsola, Addr ReglaCreada, 14, 0, 0
    Invoke ImprimirSaltoDeLinea


    ; Cerrar la biblioteca COM
    Invoke CoUninitialize
    Invoke ExitProcess, 0


ErrorInicializacionCOM:
AsigText Error0, "Error Ini COM."
    Invoke WriteConsoleA, HandleConsola, Addr Error0, 14, 0, 0
    Invoke ImprimirSaltoDeLinea

    Invoke CoUninitialize
    Invoke ExitProcess, 1

ErrorCLIDIdentifi:
AsigText Error1, "Error Identifi Clid."
    Invoke WriteConsoleA, HandleConsola, Addr Error1, 20, 0, 0
    Invoke ImprimirSaltoDeLinea

    Invoke CoUninitialize
    Invoke ExitProcess, 1

ErrorClsID:
AsigText Error2, "Error Clid."
    Invoke WriteConsoleA, HandleConsola, Addr Error2, 11, 0, 0
    Invoke ImprimirSaltoDeLinea

    Invoke CoUninitialize
    Invoke ExitProcess, 1

ErrorCoCrea:
AsigText Error3, "Error al instanciar Obj."
    Invoke WriteConsoleA, HandleConsola, Addr Error3, 25, 0, 0
    Invoke ImprimirSaltoDeLinea

    Invoke CoUninitialize
    Invoke ExitProcess, 1

ErrorCoCreaRule:
AsigText Error4, "Error al instanciar regla."
    Invoke WriteConsoleA, HandleConsola, Addr Error4, 27, 0, 0
    Invoke ImprimirSaltoDeLinea

    Invoke CoUninitialize
    Invoke ExitProcess, 1

ErrorSysAlloc:
AsigText Error5, "Error SysAlloc."
    Invoke WriteConsoleA, HandleConsola, Addr Error5, 15, 0, 0
    Invoke ImprimirSaltoDeLinea

    Invoke CoUninitialize
    Invoke ExitProcess, 1

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



End start


But for some reason, the name seems to be assigned, but the description is NOT. Any ideas, please?

_japheth

Quote from: Fraile on June 13, 2024, 01:10:49 AMIf I want to load a value into the put_name property, I need to find its offset. From what I have seen, this is calculated by enumerating each of the previously mentioned properties and multiplying by 4 if it's a 32-bit application or by 8 if it's a 64-bit application. In my case, I am developing the application with MASM32, so I multiply by 4.

get_Name - index 0
put_Name - index 1 (offset 1 * 4 = 4 bytes or 0x04)
get_Description - index 2
put_Description - index 3 (offset 3 * 4 = 12 bytes or 0x0C)

It's not that simple. The offset most likely won't start at 0, because Interfaces inherit from other interfaces, at least they inherit IUnknown ( which has 3 functions ).

QuoteBut for some reason, the name seems to be assigned, but the description is NOT. Any ideas, please?

Since COM is strongly related to C++ ( the MS variant ), each COM method has a hidden first argument, that's the object itself.

This has all been discussed multiple times - so you could probably scan the forum for code examples. The COM method calls are usually done by using macros ( "coinvoke" and the likes ).
Dummheit, gepaart mit Dreistigkeit - eine furchtbare Macht.

Fraile

Great, thank you very much, I'll take a look.

TimoVJL

COM objects are one kind of structs and are used through pointer to structs.
coinvoke macro is for that.

Vortex example for poasm :
https://masmforum.com/board/index.php/topic,16726.msg139124.html#msg139124


This also give a hint :
;http://www.masmforum.com/board/index.php?topic=5613.msg41863
.model flat,stdcall
CoMethod1Proto typedef proto :DWORD
CoMethod2Proto typedef proto :DWORD, :DWORD
CoMethod3Proto typedef proto :DWORD, :DWORD, :DWORD
CoMethod4Proto typedef proto :DWORD, :DWORD, :DWORD, :DWORD
CoMethod5Proto typedef proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
CoMethod6Proto typedef proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD

CoMethod1 typedef ptr CoMethod1Proto
CoMethod2 typedef ptr CoMethod2Proto
CoMethod3 typedef ptr CoMethod3Proto
CoMethod4 typedef ptr CoMethod4Proto
CoMethod5 typedef ptr CoMethod5Proto
CoMethod6 typedef ptr CoMethod6Proto

IRichEditOleCallback STRUCT
QueryInterface CoMethod3 ?
AddRef CoMethod1 ?
Release CoMethod1 ?
GetNewStorage CoMethod2 ?
GetInPlaceContext CoMethod4 ?
ShowContainerUI CoMethod2 ?
QueryInsertObject CoMethod4 ?
DeleteObject CoMethod2 ?
QueryAcceptData CoMethod6 ?
ContextSensitiveHelp CoMethod3 ?
GetClipboardData CoMethod4 ?
GetDragDropEffect CoMethod4 ?
GetContextMenu CoMethod5 ?
IRichEditOleCallback ENDS
May the source be with you

NoCforMe

Quote from: TimoVJL on June 13, 2024, 05:36:15 AMCOM objects are one kind of structs and are used through pointer to structs.
coinvoke macro is for that.
I looked through my Masm32 folder.
How come the only instance of coinvoke (the macro) is in JJ's MasmBasic stuff (in MasmBasic.inc)?
Is this a MasmBasic thing?
Assembly language programming should be fun. That's why I do it.

TimoVJL

At this site is speech5 text to speech and directx examples from Siekmanski
May the source be with you

Vortex

An example of the coinvoke macro :

coinvoke MACRO ppv:REQ,interface:REQ,member:REQ,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16

    FOR arg,<p16,p15,p14,p13,p12,p11,p10,p9,p8,p7,p6,p5,p4,p3,p2,p1>

        IFNB <arg>

            push arg

        ENDIF

    ENDM

    mov     eax,ppv
    push    eax
    mov     eax,DWORD PTR [eax]
    call    interface.member[eax]

ENDM

NoCforMe

Is this (or equivalent) anywhere in the MASM32 package?
Assembly language programming should be fun. That's why I do it.

Vortex

The Masm32 package does not provide a coinvoke macro.