mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-01 16:05:52 +00:00
initial version of hook str api
This commit is contained in:
@@ -219,7 +219,7 @@ namespace hook_api
|
||||
COMPLEX_NOT_SUPPORTED = -39,
|
||||
DOES_NOT_MATCH = -40, // two keylets were required to be the same type but werent
|
||||
INVALID_KEY = -41, // user supplied key was not valid
|
||||
|
||||
NOT_A_STRING = -42, // nul terminator missing from a string argument
|
||||
};
|
||||
|
||||
enum ExitType : uint8_t
|
||||
@@ -319,7 +319,12 @@ namespace hook_api
|
||||
"hook_skip",
|
||||
"hook_again",
|
||||
"hook_namespace",
|
||||
"meta_slot"
|
||||
"meta_slot",
|
||||
"str_find",
|
||||
"str_replace",
|
||||
"str_concat",
|
||||
"str_format",
|
||||
"str_compare"
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
#define EMPTY()
|
||||
#define DEFER(id) id 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(__drop, ...) VA_NARGS_IMPL(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
|
||||
#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__, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
|
||||
#define FIRST(a, b) a
|
||||
#define SECOND(a, b) b
|
||||
#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_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_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, ...)\
|
||||
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, 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 */
|
||||
|
||||
namespace hook
|
||||
@@ -631,6 +651,13 @@ namespace hook
|
||||
|
||||
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_ImportObjectAddTable(importObj, tableName, hostTable);
|
||||
WasmEdge_MemoryInstanceContext* hostMem = WasmEdge_MemoryInstanceCreate(memType);
|
||||
|
||||
@@ -5058,3 +5058,225 @@ DEFINE_HOOK_FUNCTION(
|
||||
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