无法访问传递给NASM 64位DLL的数组指针

2024-10-02 18:25:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我将指针从Python程序(使用ctypes)传递到NASM 64位DLL。在Windows调用约定中,指针在rcx和rdx中传递。这两个数组都是Int64。数组是用Python创建的,并通过以下方式传递到DLL:

PassArrayType = ctypes.c_int64 * 10
PVarrNew = PassArrayType()
OutputArrayType = ctypes.c_int64 * 1000
arrNew = OutputArrayType()
retvar = SimpleTest(ctypes.byref(PVarrNew), ctypes.byref(arrNew))

在DLL中,我可以读取rcx中的数组指针,但不能写入数组。你知道吗

例如,从rcx指向的数组中读取一个值:

push qword [rcx+32]
pop qword [tempvar]

但将值写入rcx指向的数组不起作用:

mov rax,1235
push rax
pop qword [rcx+32]

当将相同的值写入变量时:

mov rax,1235
push rax
pop qword [tempvar]

我无法读取或写入rdx指向的数组。你知道吗

所以我的问题是:

  1. 为什么我可以从rcx指向的数组中读取而不能写入它?你知道吗
  2. 为什么我不能读取或写入rdx指向的数组?你知道吗

迈克尔,谢谢你的回复。我误解了minimal的意思,认为它只指有争议的代码行。我对堆栈溢出还比较陌生,但现在我知道要发布多少代码了。下面是完整的Python代码和完整的NASM代码。Python是3.6.2。NASM是64位的。你知道吗

Python代码:

OutputArrayType = ctypes.c_int64 * 1000
arrNew = OutputArrayType()

PassArrayType = ctypes.c_int64 * 10
PVarrNew = PassArrayType()
PVarrNew[0] = id(PVarrNew)
PVarrNew[1] = 2
PVarrNew[2] = len(PVarrNew)

ThisDll = ctypes.WinDLL(r"C:/Temp2/Std_Math_Formulas.dll")
SimpleTest = ThisDll.SimpleTest
SimpleTest.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
SimpleTest.restype = ctypes.c_int64

retvar = SimpleTest(ctypes.byref(PVarrNew), ctypes.byref(arrNew))

NASM代码:

; Header Section
[BITS 64]

export SimpleTest
section .data
tempvar:  dq 0

section .text
finit

SimpleTest:

push rdi
push rbp

mov rdi,rcx
mov rbp,rdx

push qword [rcx+32]
pop qword [tempvar]

; this works with rcx, but not rdx
mov rdi,rcx
push qword [rdi+32]
pop qword [tempvar]

; this works with rcx, but not rdx
mov rax,1235
push rax
pop qword [rcx+32]

mov rax,[tempvar]

pop rbp
pop rdi
ret

我将我的DLL与以下内容进行组装和链接:

nasm -Z myfile.err -f Win64 C:\Temp2\Std_Math_Formulas.asm -l myfile.lst -F cv8 -g -o C:\Temp2\Std_Math_Formulas.obj 
GoLink Std_Math_Formulas.obj /dll /entry SimpleTest msvcrt.dll 

Tags: 代码数组ctypespoppushrax指向mov
1条回答
网友
1楼 · 发布于 2024-10-02 18:25:05

上面由Michael Petch提出的解决方案解决了这个问题。正如Michael所建议的,我从golinker命令字符串中删除了“/entry SimpleTest”,现在我可以从rcx和rdx指向的数组中读写。正确的命令字符串是:

GoLink Std_Math_Formulas.obj /dll msvcrt.dll

非常感谢你的解决方案;我非常感谢你的帮助。你知道吗

相关问题 更多 >