python安装报错ox000007b_PYTHON-Ctypes:OSError:异常:访问冲突写入0xFFFFFFFFFA1C001B

Here is a code for writing values to memory using memory mapping. When I try to run the code, I get the error

"File "MMF.py", line 26, in

memcpy(pBuf, szMsg, len(szMsg))

OSError: exception: access violation writing 0xFFFFFFFFFA1C001B"

import msvcrt, mmap

import ctypes

from ctypes import *

FILE_MAP_ALL_ACCESS = 0x04

INVALID_HANDLE_VALUE = 0xFFFFFFFF

SHMEMSIZE = 256

PAGE_READWRITE = 0x04

szName = ctypes.c_wchar_p("MyFileMappingObject")

szMsg = "Message from Python(ctypes) process"

hMapObject = windll.kernel32.CreateFileMappingA(INVALID_HANDLE_VALUE,None, PAGE_READWRITE, 0, SHMEMSIZE, szName)

print("Handle:",hMapObject)

if (hMapObject == 0):

print("Could not open file mapping object")

raise WinError()

pBuf = windll.kernel32.MapViewOfFile(hMapObject, FILE_MAP_ALL_ACCESS,0, 0, SHMEMSIZE)

print("Buffer Starting Addr:",pBuf)

if (pBuf == 0):

print("Could not map view of file")

raise WinError()

else:

print(len(szMsg))

memcpy = cdll.msvcrt.memcpy

memcpy(pBuf, szMsg, len(szMsg))

shmem = mmap.mmap(0, 256, "MyFileMappingObject_ctypes", mmap.ACCESS_WRITE)

shmem.write("Message Python process")

msvcrt.getch()

windll.kernel32.UnmapViewOfFile(pBuf)

windll.kernel32.CloseHandle(hMapObject)

shmem.close()

解决方案

Before anything, here's (almost) everything that you need: [Python 3.Docs]: ctypes - A foreign function library for Python. ctypes.wintypes is not explained, but you can see its exports by running dir(ctypes.wintypes) in the Python console. Note that all these types are simple CTypes types, I use them just for convention / consistency / readability's sake.

Your updated code (code00.py):

import sys

import ctypes as ct

import ctypes.wintypes as wt

import mmap

import msvcrt

def main(*argv):

FILE_MAP_ALL_ACCESS = 0x000F001F

INVALID_HANDLE_VALUE = -1

SHMEMSIZE = 0x100

PAGE_READWRITE = 0x04

kernel32_dll = ct.windll.kernel32

msvcrt_dll = ct.cdll.msvcrt # To be avoided

CreateFileMapping = kernel32_dll.CreateFileMappingW

CreateFileMapping.argtypes = (wt.HANDLE, wt.LPVOID, wt.DWORD, wt.DWORD, wt.DWORD, wt.LPCWSTR)

CreateFileMapping.restype = wt.HANDLE

MapViewOfFile = kernel32_dll.MapViewOfFile

MapViewOfFile.argtypes = (wt.HANDLE, wt.DWORD, wt.DWORD, wt.DWORD, ct.c_ulonglong)

MapViewOfFile.restype = wt.LPVOID

memcpy = msvcrt_dll.memcpy

memcpy.argtypes = (ct.c_void_p, ct.c_void_p, ct.c_size_t)

memcpy.restype = wt.LPVOID

RtlCopyMemory = kernel32_dll.RtlCopyMemory

RtlCopyMemory.argtypes = (wt.LPVOID, wt.LPCVOID, ct.c_ulonglong)

UnmapViewOfFile = kernel32_dll.UnmapViewOfFile

UnmapViewOfFile.argtypes = (wt.LPCVOID,)

UnmapViewOfFile.restype = wt.BOOL

CloseHandle = kernel32_dll.CloseHandle

CloseHandle.argtypes = (wt.HANDLE,)

CloseHandle.restype = wt.BOOL

GetLastError = kernel32_dll.GetLastError

file_mapping_name_ptr = ct.c_wchar_p("MyFileMappingObject")

msg = "Message from Python(ctypes) process"

msg_ptr = ct.c_wchar_p(msg)

mapping_handle = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, SHMEMSIZE, file_mapping_name_ptr)

print("Mapping object handle: 0x{:016X}".format(mapping_handle))

if not mapping_handle:

print("Could not open file mapping object: {:d}".format(GetLastError()))

raise ct.WinError()

mapped_view_ptr = MapViewOfFile(mapping_handle, FILE_MAP_ALL_ACCESS, 0, 0, SHMEMSIZE)

print("Mapped view addr: 0x{:016X}".format(mapped_view_ptr))

if not mapped_view_ptr:

print("Could not map view of file: {:d}".format(GetLastError()))

CloseHandle(mapping_handle)

raise ct.WinError()

byte_len = len(msg) * ct.sizeof(ct.c_wchar)

print("Message length: {:d} chars ({:d} bytes)".format(len(msg), byte_len))

memcpy(mapped_view_ptr, msg_ptr, byte_len) # Comment this line

RtlCopyMemory(mapped_view_ptr, msg_ptr, byte_len)

# Python vriant

shmem = mmap.mmap(0, 256, "MyFileMappingObject_ctypes", mmap.ACCESS_WRITE)

shmem.write(b"Message Python process")

print("Hit a key to clean all memory maps and exit...")

msvcrt.getch()

UnmapViewOfFile(mapped_view_ptr)

CloseHandle(mapping_handle)

shmem.close()

if __name__ == "__main__":

print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))

main(*sys.argv[1:])

print("\nDone.")

Notes:

Added the argtypes and restype for the functions. Details can be seen in the "Specifying the required argument types (function prototypes)" and "Return types" sections, and of course MS.Docs for function declarations. This is Undefined Behavior (UB) especially on 64bit: [SO]: C function called from Python via ctypes returns incorrect value (@CristiFati's answer)

memcpy's 2nd argument is a Python string, which is not the same its char * address (not to mention that in Python 3, strings are wchar_t based) that memcpy expects, this will probably also yield UB

Constants:

FILE_MAP_ALL_ACCESS's value is 0x000F001F (printed out the value from VStudio 2015), 0x04 corresponds to FILE_MAP_READ

Error converting INVALID_HANDLE_VALUE's old value to HANDLE, changed it to -1 (as in handleapi.h)

You're calling CreateFileMappingA with a c_wchar_p. That will set a name consisting of only the 1st character from the supplied string for the mapping object because each wchar_t consists of 2 bytes: 0x00 plus the corresponding char value - 'A' will be represented as 0x00 0x41 (generally this is not true - especially the 0x00 part, but in our case, it is) - so the 2nd char in the lpName argument (due to little-endianness) will be 0x00 (NUL)

According to the page above:

Accessing the standard C library through cdll.msvcrt will use an outdated version of the library that may be incompatible with the one being used by Python.

So, I also added [MS.Docs]: RtlCopyMemory function to replace memcpy (you can comment out its line, I left it there just to show that it works), as in the example ([MS.Docs]: Creating Named Shared Memory) that you took the code from, and tried to convert it ([minwinbase.h: #36]: #define CopyMemory RtlCopyMemory)

Changed naming convention to be Python compliant ([Python]: PEP 8 -- Style Guide for Python Code)

Other (non critical) changes (output formatting, moving lines of code around for a better structure, and so on ...)

Output:

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q048788549]> "e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe" code00.py

Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] 64bit on win32

Mapping object handle: 0x000000000000022C

Mapped view addr: 0x00000192912B0000

Message length: 35 chars (70 bytes)

Hit a key to clean all memory maps and exit...

Done.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值