0

I have a third-party library, and I need to use one function in python script from it. Here it is:

ReadFromBlob(PVOID blob, INT blob_size, PCSTR section, PCSTR key, const void **buffer, UINT * size)
  • blob - some pointer? to bytes to read from
  • blob_size - blob size in bytes
  • section and key - string values like "Image"
  • buffer - bytes to read to
  • size - buffer size

The documentation gives an example of how to use it:

UINT size = 0;
PVOID buffer = NULL;
ReadFromBlob(<blob>, <blob_size>, "MainImage", "Image", &buffer, &size);

I'm not familiar with C, so argument types confusing me. I need to be able to read values from the buffer in python. This is what I have so far:

from ctypes import *
lib = cdll.LoadLibrary(path_to_lib)
with open(filepath, 'rb') as file:
    data = file.read()
blob_size = c_int(len(data))
blob = cast(c_char_p(data), POINTER(c_char * blob_size.value))
b = bytes()
size = c_uint(len(b))
buffer = cast(cast(b, c_void_p), POINTER(c_char * size.value))
lib.ReadFromBlob(blob, blob_size, b"MainImage", b"Image", buffer, pointer(size))

But I still get an empty buffer in the end. Please help me.

daria
  • 23
  • 1
  • 4

1 Answers1

0

It looks like the function searches the blob for data based on the section and key and returns a pointer into the blob data and a size, so I made a test function that just echoes back the blob and size as the output parameters:

#include <windows.h>
#include <stdio.h>

__declspec(dllexport)
void ReadFromBlob(PVOID blob, INT blob_size, PCSTR section, PCSTR key, const void **buffer, UINT * size) {
    printf("section=\"%s\" key=\"%s\"\n",section,key);
    *buffer = blob;            // just echo back input data for example
    *size = (UINT)blob_size;
}

The types look like Windows types, and ctypes has a submodule wintypes with Windows definitions that help get the types right. Make sure to set the .argtypes and .restype correctly with parallel ctypes types for the Windows types. This helps ctypes check that arguments are passed correctly.

import ctypes as ct
from ctypes import wintypes as w

dll = ct.CDLL('./test')

# Note the parallels between C types and ctypes types.
# PVOID is just "pointer to void" and LPVOID mean the same thing, etc.
dll.ReadFromBlob.argtypes = w.LPVOID,w.INT,w.LPCSTR,w.LPCSTR,ct.POINTER(w.LPCVOID),w.LPUINT
dll.ReadFromBlob.restype = None

# storage for returned values, passed by reference as output parameters
buffer = w.LPCVOID()
size = w.UINT()
dll.ReadFromBlob(b'filedata',8,b'Section',b'Key',ct.byref(buffer),ct.byref(size))
print(ct.cast(buffer,ct.c_char_p).value,size.value)

Output showing the received section and key, and printing the returned blob data and size:

section="Section" key="Key"
b'filedata' 8
Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251