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.
Was first in list
https://stackoverflow.com/questions/252417/how-can-i-use-a-dll-file-from-python
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")
The problem was that you can't run a 32-bit DLL with 64-bit Python.
Thank you very much, cordial greetings.
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
link.exe internally knows these entry names
_DllMainCRTStartup for 32-bit
DllMainCRTStartup for 64-bit
EDIT
DllMain entry point (https://learn.microsoft.com/en-us/windows/win32/dlls/dllmain)
Dll entry point (https://github.com/MicrosoftDocs/SupportArticles-docs/blob/main/support/developer/visualstudio/cpp/libraries/use-c-run-time.md)
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.
Thank you very much, I will try it. :eusa_clap: