News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Call from Python to a dll library made in masm32.

Started by Fraile, September 19, 2022, 08:33:53 PM

Previous topic - Next topic

Fraile

Hello everyone,

I have this DLL made in MASM32.

.Model Flat, StdCall

.Const

.Data?

.Data



hInst      HINSTANCE   NULL
TituloBuf   DB 100 Dup (0)
TextoBuf   DB 100 Dup (0)

.Code

DllEntryPoint Proc hInstance:HINSTANCE, dwReason:DWord, lpvReserved:LPVOID
   .If dwReason == DLL_PROCESS_ATTACH
      Mov Eax, hInstance
      Mov hInst, Eax
   .ElseIf dwReason == DLL_PROCESS_DETACH

   .ElseIf dwReason == DLL_THREAD_ATTACH

   .ElseIf dwReason == DLL_THREAD_DETACH

   .EndIf
   Mov Eax, TRUE ;Return TRUE
   Ret
DllEntryPoint EndP


Mensaje Proc Titulo:DWord, Texto:DWord


   Push Esi
   Push Edi
   Push Eax
   Push Ecx


   ; Pasamos el titulo a un buffer.
   Invoke szLen, Titulo
   Mov Ecx, Eax

   Mov Esi, Titulo
   Lea Edi, TituloBuf
   Cld
   Rep Movsb

   Pop Ecx
   Pop Eax
   Pop Edi
   Pop Esi


   ; Pasamos el texto a un buffer.

   Push Esi
   Push Edi
   Push Eax
   Push Ecx


   Invoke szLen, Texto
   Mov Ecx, Eax

   Mov Esi, Texto
   Lea Edi, TextoBuf
   Cld
   Rep Movsb


   Invoke MessageBox, 0, Offset TextoBuf, Offset TituloBuf, MB_OK

   Pop Ecx
   Pop Eax
   Pop Edi
   Pop Esi

   Ret
Mensaje EndP


End DllEntryPoint


How can I use it from Python?

Thank you very much to all.

TimoVJL

Was first in list
https://stackoverflow.com/questions/252417/how-can-i-use-a-dll-file-from-python
May the source be with you

Fraile


Thank you very much for your answer, but it gives me this error:



========== RESTART: D:/python/masm32/Python_Llamada/Python_Llamada.py ==========
Traceback (most recent call last):
  File "D:/python/masm32/Python_Llamada/Python_Llamada.py", line 3, in <module>
    MiDll = cdll.LoadLibrary("D:\\python\\masm32\\Python_Llamada\\DLLMensaje.dll")
  File "C:\Users\Fraile\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py", line 452, in LoadLibrary
    return self._dlltype(name)
  File "C:\Users\Fraile\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py", line 374, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: [WinError 193] %1 no es una aplicación Win32 válida


I attach the call in python 3.10.

from ctypes import *

MiDll = cdll.LoadLibrary("D:\\python\\masm32\\Python_Llamada\\DLLMensaje.dll")




Fraile

The problem was that you can't run a 32-bit DLL with 64-bit Python.

Thank you very much, cordial greetings.

hutch--

It take some practice but 64 bit MASM DLLs work fine and once you understand how 64 bit works, they are very similar to write as a 32 bit DLL.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm64\include64\masm64rt.inc

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    ; -------------------------------------------
    ; Build this DLL with the provided MAKEIT.BAT
    ; -------------------------------------------

      .data?
        DLLinstance dq ?

      .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

LibMain proc instance:QWORD,reason:QWORD,unused:QWORD

    .if reason == DLL_PROCESS_ATTACH
      mrm DLLinstance, instance             ; copy local to global
      mov rax, TRUE                         ; return TRUE so DLL will start

    .elseif reason == DLL_PROCESS_DETACH

    .elseif reason == DLL_THREAD_ATTACH

    .elseif reason == DLL_THREAD_DETACH

    .endif

    ret

LibMain endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

  comment * -------------------------------------------------------

          You should add the procedures your DLL requires AFTER the
          LibMain procedure. For each procedure that you wish to
          EXPORT you must place its name in the DEF file so that the
          linker will know which procedures to put in the EXPORT
          table in the DLL. Use the following syntax AFTER the
          LIBRARY name on the 1st line.

          LIBRARY DLLname               ; the name of the DLL you are creating
            EXPORTS YourProcName        ; the name of EACH proc you EXPORT
            EXPORTS Any other proc      ; you declare each proc you EXPORT

          A library file will be created with the same name as the dll.
          If you are going to use "includelib" then you will need to link
          this library into the calling application. You will also need to
          create a prototype for each exported procedure you call. They
          occure in this form.

          EXTERNDEF YourProcName:PROC

          ------------------------------------------------------- *

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

TestMsgBox proc hndl:QWORD,text:QWORD,titl:QWORD,mbstyle:QWORD

    fn MessageBox,hndl,text,titl,mbstyle
  ; ----------------------
  ; return value is in RAX
  ; ----------------------
    ret

TestMsgBox endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end

TimoVJL

#5
link.exe internally knows these entry names
_DllMainCRTStartup for 32-bit
DllMainCRTStartup for 64-bit

EDIT
DllMain entry point
Dll entry point

If hinstDLL isn't needed, just return TRUE
DllMainCRTStartup proc
    mov eax, 1
    ret
DllMainCRTStartup endp

EDIT
QuotelpvReserved [in]

If fdwReason is DLL_PROCESS_ATTACH, lpvReserved is NULL for dynamic loads and non-NULL for static loads.

If fdwReason is DLL_PROCESS_DETACH, lpvReserved is NULL if FreeLibrary has been called or the DLL load failed and non-NULL if the process is terminating.
May the source be with you

Fraile