mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-05 16:57:53 +00:00
initial version of hook str api
This commit is contained in:
@@ -219,7 +219,7 @@ namespace hook_api
|
|||||||
COMPLEX_NOT_SUPPORTED = -39,
|
COMPLEX_NOT_SUPPORTED = -39,
|
||||||
DOES_NOT_MATCH = -40, // two keylets were required to be the same type but werent
|
DOES_NOT_MATCH = -40, // two keylets were required to be the same type but werent
|
||||||
INVALID_KEY = -41, // user supplied key was not valid
|
INVALID_KEY = -41, // user supplied key was not valid
|
||||||
|
NOT_A_STRING = -42, // nul terminator missing from a string argument
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ExitType : uint8_t
|
enum ExitType : uint8_t
|
||||||
@@ -319,7 +319,12 @@ namespace hook_api
|
|||||||
"hook_skip",
|
"hook_skip",
|
||||||
"hook_again",
|
"hook_again",
|
||||||
"hook_namespace",
|
"hook_namespace",
|
||||||
"meta_slot"
|
"meta_slot",
|
||||||
|
"str_find",
|
||||||
|
"str_replace",
|
||||||
|
"str_concat",
|
||||||
|
"str_format",
|
||||||
|
"str_compare"
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
#define EMPTY()
|
#define EMPTY()
|
||||||
#define DEFER(id) id EMPTY()
|
#define DEFER(id) id EMPTY()
|
||||||
#define OBSTRUCT(...) __VA_ARGS__ DEFER(EMPTY)()
|
#define OBSTRUCT(...) __VA_ARGS__ DEFER(EMPTY)()
|
||||||
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
|
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, N, ...) N
|
||||||
#define VA_NARGS(__drop, ...) VA_NARGS_IMPL(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
|
#define VA_NARGS(__drop, ...) VA_NARGS_IMPL(__VA_ARGS__, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
|
||||||
#define FIRST(a, b) a
|
#define FIRST(a, b) a
|
||||||
#define SECOND(a, b) b
|
#define SECOND(a, b) b
|
||||||
#define STRIP_TYPES(...) FOR_VARS(SECOND, 0, __VA_ARGS__)
|
#define STRIP_TYPES(...) FOR_VARS(SECOND, 0, __VA_ARGS__)
|
||||||
@@ -41,6 +41,8 @@
|
|||||||
#define FOR_VAR_8(T, S, a, ...) FOR_VAR_1(T, S, a) DELIM(S) FOR_VAR_7(T, S, __VA_ARGS__)
|
#define FOR_VAR_8(T, S, a, ...) FOR_VAR_1(T, S, a) DELIM(S) FOR_VAR_7(T, S, __VA_ARGS__)
|
||||||
#define FOR_VAR_9(T, S, a, ...) FOR_VAR_1(T, S, a) DELIM(S) FOR_VAR_8(T, S, __VA_ARGS__)
|
#define FOR_VAR_9(T, S, a, ...) FOR_VAR_1(T, S, a) DELIM(S) FOR_VAR_8(T, S, __VA_ARGS__)
|
||||||
#define FOR_VAR_10(T, S, a, ...) FOR_VAR_1(T, S, a) DELIM(S) FOR_VAR_9(T, S, __VA_ARGS__)
|
#define FOR_VAR_10(T, S, a, ...) FOR_VAR_1(T, S, a) DELIM(S) FOR_VAR_9(T, S, __VA_ARGS__)
|
||||||
|
#define FOR_VAR_11(T, S, a, ...) FOR_VAR_1(T, S, a) DELIM(S) FOR_VAR_10(T, S, __VA_ARGS__)
|
||||||
|
#define FOR_VAR_12(T, S, a, ...) FOR_VAR_1(T, S, a) DELIM(S) FOR_VAR_11(T, S, __VA_ARGS__)
|
||||||
#define FOR_VARS(T, S, ...)\
|
#define FOR_VARS(T, S, ...)\
|
||||||
DEFER(CAT(FOR_VAR_,VA_NARGS(NULL, __VA_ARGS__))CAT(LPAREN T COMMA S COMMA OBSTRUCT(__VA_ARGS__) RPAREN))
|
DEFER(CAT(FOR_VAR_,VA_NARGS(NULL, __VA_ARGS__))CAT(LPAREN T COMMA S COMMA OBSTRUCT(__VA_ARGS__) RPAREN))
|
||||||
|
|
||||||
|
|||||||
@@ -222,6 +222,26 @@ namespace hook_api
|
|||||||
|
|
||||||
DECLARE_HOOK_FUNCTION(int64_t, meta_slot, uint32_t slot_no );
|
DECLARE_HOOK_FUNCTION(int64_t, meta_slot, uint32_t slot_no );
|
||||||
|
|
||||||
|
|
||||||
|
DECLARE_HOOK_FUNCTION(int64_t, str_find, uint32_t hread_ptr, uint32_t hread_len,
|
||||||
|
uint32_t nread_ptr, uint32_t nread_len,
|
||||||
|
uint32_t mode, uint32_t n);
|
||||||
|
DECLARE_HOOK_FUNCTION(int64_t, str_replace, uint32_t write_ptr, uint32_t write_len,
|
||||||
|
uint32_t hread_ptr, uint32_t hread_len,
|
||||||
|
uint32_t nread_ptr, uint32_t nread_len,
|
||||||
|
uint32_t rread_ptr, uint32_t rread_len,
|
||||||
|
uint32_t mode, uint32_t n);
|
||||||
|
DECLARE_HOOK_FUNCTION(int64_t, str_compare, uint32_t fread_ptr, uint32_t fread_len,
|
||||||
|
uint32_t sread_ptr, uint32_t sread_len,
|
||||||
|
uint32_t mode);
|
||||||
|
DECLARE_HOOK_FUNCTION(int64_t, str_format, uint32_t write_ptr, uint32_t write_len,
|
||||||
|
uint32_t fread_ptr, uint32_t fread_len,
|
||||||
|
uint64_t a, uint64_t b, uint64_t c, uint64_t d,
|
||||||
|
uint64_t e, uint64_t f, uint64_t g, uint64_t h);
|
||||||
|
DECLARE_HOOK_FUNCTION(int64_t, str_concat, uint32_t write_ptr, uint32_t write_len,
|
||||||
|
uint32_t read_ptr, uint32_t read_len,
|
||||||
|
uint64_t operand, uint32_t operand_type);
|
||||||
|
|
||||||
} /* end namespace hook_api */
|
} /* end namespace hook_api */
|
||||||
|
|
||||||
namespace hook
|
namespace hook
|
||||||
@@ -631,6 +651,13 @@ namespace hook
|
|||||||
|
|
||||||
ADD_HOOK_FUNCTION(meta_slot, ctx);
|
ADD_HOOK_FUNCTION(meta_slot, ctx);
|
||||||
|
|
||||||
|
|
||||||
|
ADD_HOOK_FUNCTION(str_find, ctx);
|
||||||
|
ADD_HOOK_FUNCTION(str_replace, ctx);
|
||||||
|
ADD_HOOK_FUNCTION(str_compare, ctx);
|
||||||
|
ADD_HOOK_FUNCTION(str_concat, ctx);
|
||||||
|
ADD_HOOK_FUNCTION(str_format, ctx);
|
||||||
|
|
||||||
WasmEdge_TableInstanceContext* hostTable = WasmEdge_TableInstanceCreate(tableType);
|
WasmEdge_TableInstanceContext* hostTable = WasmEdge_TableInstanceCreate(tableType);
|
||||||
WasmEdge_ImportObjectAddTable(importObj, tableName, hostTable);
|
WasmEdge_ImportObjectAddTable(importObj, tableName, hostTable);
|
||||||
WasmEdge_MemoryInstanceContext* hostMem = WasmEdge_MemoryInstanceCreate(memType);
|
WasmEdge_MemoryInstanceContext* hostMem = WasmEdge_MemoryInstanceCreate(memType);
|
||||||
|
|||||||
@@ -5058,3 +5058,225 @@ DEFINE_HOOK_FUNCTION(
|
|||||||
return slot_into;
|
return slot_into;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DEFINE_HOOK_FUNCTION(
|
||||||
|
int64_t,
|
||||||
|
str_find,
|
||||||
|
uint32_t hread_ptr, uint32_t hread_len,
|
||||||
|
uint32_t nread_ptr, uint32_t nread_len,
|
||||||
|
uint32_t mode, uint32_t n)
|
||||||
|
{
|
||||||
|
HOOK_SETUP(); // populates memory_ctx, memory, memory_length, applyCtx, hookCtx on current stack
|
||||||
|
|
||||||
|
if (NOT_IN_BOUNDS(hread_ptr, hread_len, memory_length) ||
|
||||||
|
NOT_IN_BOUNDS(nread_ptr, nread_len, memory_length))
|
||||||
|
return OUT_OF_BOUNDS;
|
||||||
|
|
||||||
|
if (hread_len > 32*1024)
|
||||||
|
return TOO_BIG;
|
||||||
|
|
||||||
|
if (nread_len > 256)
|
||||||
|
return TOO_BIG;
|
||||||
|
|
||||||
|
if (hread_len == 0)
|
||||||
|
return TOO_SMALL;
|
||||||
|
|
||||||
|
if (mode > 3)
|
||||||
|
return INVALID_ARGUMENT;
|
||||||
|
|
||||||
|
if (n >= hread_len)
|
||||||
|
return INVALID_ARGUMENT;
|
||||||
|
|
||||||
|
// overload for str_len
|
||||||
|
if (nread_ptr == 0)
|
||||||
|
{
|
||||||
|
if (nread_len != 0)
|
||||||
|
return INVALID_ARGUMENT;
|
||||||
|
|
||||||
|
return strnlen((const char*)(hread_ptr + memory), hread_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool insensitive = mode % 2 == 1;
|
||||||
|
|
||||||
|
// just the haystack based on where to start search from
|
||||||
|
hread_ptr += n;
|
||||||
|
hread_len -= n;
|
||||||
|
|
||||||
|
if (NOT_IN_BOUNDS(hread_ptr, hread_len, memory_length))
|
||||||
|
return OUT_OF_BOUNDS;
|
||||||
|
|
||||||
|
std::string_view haystack{(const char*)(memory + hread_ptr), hread_len};
|
||||||
|
if (mode < 2)
|
||||||
|
{
|
||||||
|
// plain string mode: 0 == case sensitive
|
||||||
|
|
||||||
|
std::string_view needle{(const char*)(memory + nread_ptr), nread_len};
|
||||||
|
|
||||||
|
auto found = std::search(
|
||||||
|
haystack.begin(), haystack.end(),
|
||||||
|
needle.begin(), needle.end(),
|
||||||
|
insensitive
|
||||||
|
? [](char ch1, char ch2)
|
||||||
|
{
|
||||||
|
return std::toupper(ch1) == std::toupper(ch2);
|
||||||
|
}
|
||||||
|
: [](char ch1, char ch2)
|
||||||
|
{
|
||||||
|
return ch1 == ch2;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (found == haystack.end())
|
||||||
|
return DOESNT_EXIST;
|
||||||
|
return found - haystack.begin();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// regex mode mode: 2 == case sensitive
|
||||||
|
|
||||||
|
return NOT_IMPLEMENTED;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_HOOK_FUNCTION(
|
||||||
|
int64_t,
|
||||||
|
str_replace,
|
||||||
|
uint32_t write_ptr, uint32_t write_len,
|
||||||
|
uint32_t hread_ptr, uint32_t hread_len,
|
||||||
|
uint32_t nread_ptr, uint32_t nread_len,
|
||||||
|
uint32_t rread_ptr, uint32_t rread_len,
|
||||||
|
uint32_t mode, uint32_t n)
|
||||||
|
{
|
||||||
|
HOOK_SETUP(); // populates memory_ctx, memory, memory_length, applyCtx, hookCtx on current stack
|
||||||
|
|
||||||
|
if (NOT_IN_BOUNDS(write_ptr, write_len, memory_length) ||
|
||||||
|
NOT_IN_BOUNDS(hread_ptr, hread_len, memory_length) ||
|
||||||
|
NOT_IN_BOUNDS(nread_ptr, nread_len, memory_length) ||
|
||||||
|
NOT_IN_BOUNDS(rread_ptr, rread_len, memory_length))
|
||||||
|
return OUT_OF_BOUNDS;
|
||||||
|
|
||||||
|
if (hread_len > 32*1024)
|
||||||
|
return TOO_BIG;
|
||||||
|
|
||||||
|
if (nread_len > 256)
|
||||||
|
return TOO_BIG;
|
||||||
|
|
||||||
|
if (hread_len == 0)
|
||||||
|
return TOO_SMALL;
|
||||||
|
|
||||||
|
if (nread_len == 0)
|
||||||
|
return TOO_SMALL;
|
||||||
|
|
||||||
|
return NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_HOOK_FUNCTION(
|
||||||
|
int64_t,
|
||||||
|
str_compare,
|
||||||
|
uint32_t fread_ptr, uint32_t fread_len,
|
||||||
|
uint32_t sread_ptr, uint32_t sread_len,
|
||||||
|
uint32_t mode)
|
||||||
|
{
|
||||||
|
HOOK_SETUP(); // populates memory_ctx, memory, memory_length, applyCtx, hookCtx on current stack
|
||||||
|
|
||||||
|
if (NOT_IN_BOUNDS(fread_ptr, fread_len, memory_length) ||
|
||||||
|
NOT_IN_BOUNDS(sread_ptr, sread_len, memory_length))
|
||||||
|
return OUT_OF_BOUNDS;
|
||||||
|
|
||||||
|
if (mode > 1)
|
||||||
|
return INVALID_ARGUMENT;
|
||||||
|
|
||||||
|
if (fread_len > 255 || sread_len > 255)
|
||||||
|
return TOO_BIG;
|
||||||
|
|
||||||
|
if (fread_len == 0 || sread_len == 0)
|
||||||
|
return TOO_SMALL;
|
||||||
|
|
||||||
|
bool insensitive = mode == 1;
|
||||||
|
|
||||||
|
const char* it1 = (const char*)(memory + fread_ptr);
|
||||||
|
const char* it2 = (const char*)(memory + sread_ptr);
|
||||||
|
const char* end1 = it1 + fread_len;
|
||||||
|
const char* end2 = it2 + sread_len;
|
||||||
|
|
||||||
|
if (insensitive)
|
||||||
|
for(; it1 < end1 && it2 < end2; ++it1, ++it2)
|
||||||
|
{
|
||||||
|
if (*it1 < *it2)
|
||||||
|
return 0;
|
||||||
|
if (*it1 > *it2)
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
for(; it1 < end1 && it2 < end2; ++it1, ++it2)
|
||||||
|
{
|
||||||
|
if (std::tolower(*it1) < std::tolower(*it2))
|
||||||
|
return 0;
|
||||||
|
if (std::tolower(*it1) > std::tolower(*it2))
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_HOOK_FUNCTION(
|
||||||
|
int64_t,
|
||||||
|
str_format,
|
||||||
|
uint32_t write_ptr, uint32_t write_len,
|
||||||
|
uint32_t fread_ptr, uint32_t fread_len,
|
||||||
|
uint64_t a, uint64_t b, uint64_t c, uint64_t d,
|
||||||
|
uint64_t e, uint64_t f, uint64_t g, uint64_t h)
|
||||||
|
{
|
||||||
|
HOOK_SETUP(); // populates memory_ctx, memory, memory_length, applyCtx, hookCtx on current stack
|
||||||
|
|
||||||
|
if (NOT_IN_BOUNDS(write_ptr, write_len, memory_length) ||
|
||||||
|
NOT_IN_BOUNDS(fread_ptr, fread_len, memory_length))
|
||||||
|
return OUT_OF_BOUNDS;
|
||||||
|
|
||||||
|
if (write_len == 0 || fread_len == 0)
|
||||||
|
return TOO_SMALL;
|
||||||
|
|
||||||
|
if (write_len > 1024 || fread_len > 1024)
|
||||||
|
return TOO_BIG;
|
||||||
|
|
||||||
|
// check if there's a nul terminator on format string
|
||||||
|
bool hasnul = false;
|
||||||
|
const char* fmtptr = (const char*)(memory + fread_ptr);
|
||||||
|
for (int i = 0; i < fread_len; ++i)
|
||||||
|
if (fmtptr[i] == '\0')
|
||||||
|
{
|
||||||
|
hasnul = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasnul)
|
||||||
|
return NOT_A_STRING;
|
||||||
|
|
||||||
|
//int result = snprintf(write_ptr + memory, write_len, fread_ptr + memory, a,b,c,d,e,f,g,h);
|
||||||
|
//RH NOTE: can't do this ^ because string arguments can expose non-wasm memory
|
||||||
|
// will need to parse format string ourselves, or implement our own.
|
||||||
|
return NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_HOOK_FUNCTION(
|
||||||
|
int64_t,
|
||||||
|
str_concat,
|
||||||
|
uint32_t write_ptr, uint32_t write_len,
|
||||||
|
uint32_t read_ptr, uint32_t read_len,
|
||||||
|
uint64_t operand, uint32_t operand_type)
|
||||||
|
{
|
||||||
|
HOOK_SETUP(); // populates memory_ctx, memory, memory_length, applyCtx, hookCtx on current stack
|
||||||
|
|
||||||
|
if (NOT_IN_BOUNDS(write_ptr, write_len, memory_length) ||
|
||||||
|
NOT_IN_BOUNDS(read_ptr, read_len, memory_length))
|
||||||
|
return OUT_OF_BOUNDS;
|
||||||
|
|
||||||
|
if (write_len > 1024 || read_len > 1024)
|
||||||
|
return TOO_BIG;
|
||||||
|
if (write_len == 0 || read_len == 0)
|
||||||
|
return TOO_SMALL;
|
||||||
|
if (write_len < read_len)
|
||||||
|
return TOO_SMALL;
|
||||||
|
|
||||||
|
return NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user