From 8d1d43edabe159b00d594831a9c953cfd5ac1cff Mon Sep 17 00:00:00 2001 From: hyugogirubato <65763543+hyugogirubato@users.noreply.github.com> Date: Tue, 28 Apr 2026 19:54:09 +0200 Subject: [PATCH] fix old std vector impl --- keydive/keydive.js | 59 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/keydive/keydive.js b/keydive/keydive.js index d5e85cf..cfb920f 100644 --- a/keydive/keydive.js +++ b/keydive/keydive.js @@ -134,12 +134,8 @@ Memory.readStdStringAny = function (address) { // Doesn't match any current STL; kept as a last-resort fallback. // https://learnfrida.info/intermediate_usage/#stdvector Memory.readStdVector = function (address) { - // https://learnfrida.info/intermediate_usage/#stdvector - // Read the vector size (2 bytes) at offset 8 - let size = Memory.readU16(address.add(8)); - - // Read pointer to the start of the vector data (at offset 0) - const data = Memory.readByteArray(address.readPointer(), size); + let length = Memory.readU16(address.add(8)); + const data = Memory.readByteArray(address.readPointer(), length); /* const buffer = new Uint8Array(data); @@ -154,6 +150,55 @@ Memory.readStdVector = function (address) { return data; } +// android::Vector from utils/Vector.h (vptr-prefixed because VectorImpl has a virtual dtor): +// [vptr][void* mStorage][size_t mCount][uint32_t mFlags][size_t mItemSize] +// Data ptr = mStorage @+pSize, byte count = mCount @+2*pSize (T = uint8_t). +Memory.readAndroidVector = function (address) { + try { + const dataPtr = address.add(Process.pointerSize).readPointer(); + if (dataPtr.isNull() || dataPtr.compare(ptr(0x1000)) < 0) return null; + const count = address.add(2 * Process.pointerSize).readU32(); + if (count === 0 || count > 0x10000000) return null; + return Memory.readByteArray(dataPtr, count); + } catch (e) { + return null; + } +} + +// std::vector (libc++ and libstdc++ C++11): +// [pointer begin][pointer end][pointer capacity_end] +// For vector the byte count is end - begin. +Memory.readStdVectorRange = function (address) { + try { + const begin = address.readPointer(); + const end = address.add(Process.pointerSize).readPointer(); + if (begin.isNull() || begin.compare(ptr(0x1000)) < 0) return null; + if (end.compare(begin) < 0) return null; + const length = end.sub(begin).toInt32(); + if (length === 0 || length > 0x10000000) return null; + return Memory.readByteArray(begin, length); + } catch (e) { + return null; + } +} + +// Try every known vector layout and return the first plausible result. +Memory.readStdVectorAny = function (address) { + const readers = [ + Memory.readAndroidVector, // android::Vector + Memory.readStdVectorRange, // std::vector + Memory.readStdVector, // legacy U16-at-offset-8 layout + ]; + for (const reader of readers) { + try { + const data = reader(address); + if (data && data.byteLength > 0) return data; + } catch (e) { /* try next */ + } + } + return null; +} + // Utility for encoding strings into byte arrays (UTF-8). // https://gist.github.com/Yaffle/5458286#file-textencodertextdecoder-js class TextEncoder { @@ -768,7 +813,7 @@ function WVDrmPlugin_provideProvisionResponse(address) { // Extract and dump the relevant arguments for (let i = 0; i < 4; i++) { try { - const responseData = Memory.readStdVector(args[i]); + const responseData = Memory.readStdVectorAny(args[i]); if (responseData) { dumped = true; send('provisioning_response', responseData);