首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Python中的Security.framework类型

使用Python中的Security.framework类型
EN

Stack Overflow用户
提问于 2014-05-13 21:38:29
回答 1查看 520关注 0票数 2

我正在编写一个Python,它通过ctype从OS上调用Security.framework函数。

我能够用Python创建一个CFDictionaryRef和CFStringRef,并将字符串存储在字典中,但现在我正在添加Security.framework查询对象(kSecClasskSecMatchLimitkSecReturnAttributes、…)我得到了以下坠机:

代码语言:javascript
复制
objc[28201]: Method cache corrupted. This may be a message to an invalid object, or a memory error somewhere else.
objc[28201]: receiver 0x7fff724fcdf8, SEL 0x7fff8d814fe5, isa 0x7fff724f5f90, cache 0x7fff724f5fa0, buckets 0x7fff8842ffe3, mask 0x5, occupied 0x0, wrap bucket 0x7fff8842ffe3
objc[28201]: receiver 0 bytes, buckets 0 bytes
objc[28201]: selector 'hash'
objc[28201]: isa '(null)'
objc[28201]: Method cache corrupted.
zsh: illegal hardware instruction  python kc.py

我尝试使用包含对象的ctype数组调用CFDictionaryCreate(),并调用CFMutableDictionaryCreate()然后CFDictionarySetValue。见下文。

代码语言:javascript
复制
import ctypes
import ctypes.util
from ctypes import CFUNCTYPE

security = ctypes.CDLL(ctypes.util.find_library('Security'))
foundation = ctypes.CDLL(ctypes.util.find_library('Foundation'))

CFDictionaryRef = ctypes.c_void_p
CFMutableDictionaryRef = ctypes.c_void_p
CFTypeRef = ctypes.c_void_p
CFIndex = ctypes.c_long

CFDictionaryCreate = CFUNCTYPE(CFDictionaryRef, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, CFIndex, ctypes.c_void_p, ctypes.c_void_p)(('CFDictionaryCreate', foundation))
CFDictionaryCreateMutable = CFUNCTYPE(CFMutableDictionaryRef, CFIndex, ctypes.c_void_p, ctypes.c_void_p)(('CFDictionaryCreateMutable', foundation))
CFDictionarySetValue = CFUNCTYPE(CFMutableDictionaryRef, ctypes.c_void_p, ctypes.c_void_p)(('CFDictionarySetValue', foundation))

def createCFDictionary(items):
    """
    Create a CFDictionaryRef from items = [(CFTypeRef, CFTypeRef), ...]
    """
    # Create C arrays for the keys and values (which are cast as CFTypeRefs).
    keys_array = (CFTypeRef * len(items))(*[ctypes.cast(k, CFTypeRef) for k, v in items])
    values_array = (CFTypeRef * len(items))(*[ctypes.cast(v, CFTypeRef) for k, v in items])

    return CFDictionaryCreate(None,
                              keys_array, values_array, len(items),
                              foundation.kCFTypeDictionaryKeyCallBacks, foundation.kCFTypeDictionaryValueCallBacks)

# 1. Create a CFDictionary with the items in it (crashes).
query = createCFDictionary([(security.kSecClass, security.kSecClassCertificate)])


# 2a. Create a CFMutableDictionary.
query = CFDictionaryCreateMutable(0, foundation.kCFTypeDictionaryKeyCallBacks, foundation.kCFTypeDictionaryValueCallBacks)

# 2b. Add items to it (crashes).
CFDictionarySetValue(query, security.kSecClass, security.kSecClassCertificate)

如果这是一种更简单的解决方案,我很乐意使用PyObjC而不是ctype;然而,我对它不太熟悉,也无法导入Security.framework。

OS 10.9.2,Python2.7.5(随OS一起包括)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-14 14:21:56

我正在调查第二个案例,因为它看起来更简单。

您的CFDictionarySetValue缺少了dict参数。修复后,security.kSecClass似乎实际上返回了一个函数引用,这是错误的。我认为你需要:

代码语言:javascript
复制
ctypes.c_void_p.in_dll(foundation, 'kSecClass')

这将导致将正确的值传递给函数(如lldb中所示)。

不知何故,kCFTypeDictionaryKeyCallBacks结构仍然无法使用该机制,这可能是因为符号实际上指向的是结构,而不是指向结构的指针。我想不出任何方法让ctype返回符号所代表的实际地址(这就是您想传递给CFDictionaryCreateMutable的地址),而不是那个符号的值( 0,因为这是该结构的第一个成员的值)。

您可以自己构造回调,这应该更容易一些,因为您可以在ctype中定义struct类型,然后获取所需的函数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23642046

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档