Skip to content

Commit be67e81

Browse files
xusheng6claude
andcommitted
[emulator] Type the stdin callback buffer as void* for a writable binding
The stdin callback's output buffer was a char* in the FFI, so the generated Python binding exposed it as c_char_p and ctypes handed the callback an immutable bytes copy, making the memmove into it write to the wrong memory. Type the buffer void* across the FFI/C++ bridge so the generated binding uses a writable c_void_p pointer; the Python callback now receives the real buffer address to write into. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent a2ae96e commit be67e81

5 files changed

Lines changed: 11 additions & 6 deletions

File tree

plugins/emulator/api/emulatorapi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ namespace BinaryNinjaEmulatorAPI
6060
uint32_t intrinsic, const uint64_t* params, size_t paramCount,
6161
uint64_t* outValues, uint32_t* outRegs, size_t maxCount, size_t* outCount);
6262
static void StdoutCallbackBridge(void* ctxt, BNILEmulator* emu, const char* data, size_t len);
63-
static size_t StdinCallbackBridge(void* ctxt, BNILEmulator* emu, char* buf, size_t maxLen);
63+
static size_t StdinCallbackBridge(void* ctxt, BNILEmulator* emu, void* buf, size_t maxLen);
6464

6565
public:
6666
LLILEmulator(Ref<BinaryView> view);

plugins/emulator/api/ffi.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,10 @@ extern "C"
144144
bool (*callback)(void* ctxt, BNILEmulator* emu, size_t instrIndex));
145145
EMULATOR_FFI_API void BNILEmulatorSetStdoutCallback(BNILEmulator* emu, void* ctxt,
146146
void (*callback)(void* ctxt, BNILEmulator* emu, const char* data, size_t len));
147+
// buf is a writable output buffer of maxLen bytes (typed void* so the generated bindings
148+
// expose it as a writable pointer rather than an immutable string).
147149
EMULATOR_FFI_API void BNILEmulatorSetStdinCallback(BNILEmulator* emu, void* ctxt,
148-
size_t (*callback)(void* ctxt, BNILEmulator* emu, char* buf, size_t maxLen));
150+
size_t (*callback)(void* ctxt, BNILEmulator* emu, void* buf, size_t maxLen));
149151
EMULATOR_FFI_API void BNILEmulatorRequestStop(BNILEmulator* emu);
150152
EMULATOR_FFI_API void BNILEmulatorReset(BNILEmulator* emu);
151153

plugins/emulator/api/ilemulator.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,10 +304,10 @@ void LLILEmulator::StdoutCallbackBridge(void* ctxt, BNILEmulator*, const char* d
304304
}
305305

306306

307-
size_t LLILEmulator::StdinCallbackBridge(void* ctxt, BNILEmulator*, char* buf, size_t maxLen)
307+
size_t LLILEmulator::StdinCallbackBridge(void* ctxt, BNILEmulator*, void* buf, size_t maxLen)
308308
{
309309
LLILEmulator* self = (LLILEmulator*)ctxt;
310-
return self->m_stdinCallback(self, buf, maxLen);
310+
return self->m_stdinCallback(self, static_cast<char*>(buf), maxLen);
311311
}
312312

313313

plugins/emulator/api/python/ilemulator.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,9 +551,12 @@ def set_stdin_callback(
551551
Return ``b''`` for EOF. Pass ``None`` to remove the callback.
552552
"""
553553
self._stdin_callback = callback
554+
# buf is a writable, non-null-terminated output buffer. It is typed void* in the FFI
555+
# (hence c_void_p here) so the callback receives the raw address to memmove into,
556+
# rather than the immutable bytes copy ctypes produces for a c_char_p parameter.
554557
_CB_T = ctypes.CFUNCTYPE(ctypes.c_ulonglong, ctypes.c_void_p,
555558
ctypes.POINTER(core.BNILEmulator),
556-
ctypes.c_char_p, ctypes.c_ulonglong)
559+
ctypes.c_void_p, ctypes.c_ulonglong)
557560
if callback is None:
558561
core.BNILEmulatorSetStdinCallback(self._get_base(), None, ctypes.cast(None, _CB_T))
559562
self._stdin_cb = None

plugins/emulator/core/ilemulator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,7 @@ void BNILEmulatorSetStdoutCallback(BNILEmulator* emu, void* ctxt,
806806

807807

808808
void BNILEmulatorSetStdinCallback(BNILEmulator* emu, void* ctxt,
809-
size_t (*callback)(void*, BNILEmulator*, char*, size_t))
809+
size_t (*callback)(void*, BNILEmulator*, void*, size_t))
810810
{
811811
if (callback)
812812
{

0 commit comments

Comments
 (0)