DBG: format function improvements
This commit is contained in:
parent
668ea4ef57
commit
d5e224a7a5
|
@ -259,12 +259,20 @@ typedef enum
|
|||
CB_LAST
|
||||
} CBTYPE;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FORMAT_ERROR, //generic failure (no message)
|
||||
FORMAT_SUCCESS, //success
|
||||
FORMAT_ERROR_MESSAGE, //formatting failed but an error was put in the buffer (there are always at least 511 characters available).
|
||||
FORMAT_BUFFER_TOO_SMALL //buffer too small (x64dbg will retry until the buffer is big enough)
|
||||
} FORMATRESULT;
|
||||
|
||||
//typedefs
|
||||
typedef void (*CBPLUGIN)(CBTYPE cbType, void* callbackInfo);
|
||||
typedef bool (*CBPLUGINCOMMAND)(int argc, char** argv);
|
||||
typedef void (*CBPLUGINSCRIPT)();
|
||||
typedef duint(*CBPLUGINEXPRFUNCTION)(int argc, duint* argv, void* userdata);
|
||||
typedef bool(*CBPLUGINFORMATFUNCTION)(char* dest, size_t destCount, int argc, char* argv[], duint value, void* userdata);
|
||||
typedef FORMATRESULT(*CBPLUGINFORMATFUNCTION)(char* dest, size_t destCount, int argc, char* argv[], duint value, void* userdata);
|
||||
|
||||
//exports
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -30,11 +30,12 @@ template<typename... Ts>
|
|||
static bool RegisterEasy(const String & name, duint(*cbFunction)(Ts...))
|
||||
{
|
||||
auto aliases = StringUtils::Split(name, ',');
|
||||
if(!ExpressionFunctions::Register(aliases[0], sizeof...(Ts), [cbFunction](int argc, duint * argv, void* userdata)
|
||||
{
|
||||
return callFunc(argv, cbFunction, typename gens<sizeof...(Ts)>::type());
|
||||
}))
|
||||
return false;
|
||||
auto tempFunc = [cbFunction](int argc, duint * argv, void* userdata)
|
||||
{
|
||||
return callFunc(argv, cbFunction, typename gens<sizeof...(Ts)>::type());
|
||||
};
|
||||
if(!ExpressionFunctions::Register(aliases[0], sizeof...(Ts), tempFunc))
|
||||
return false;
|
||||
for(size_t i = 1; i < aliases.size(); i++)
|
||||
ExpressionFunctions::RegisterAlias(aliases[0], aliases[i]);
|
||||
return true;
|
||||
|
|
|
@ -10,13 +10,27 @@ void FormatFunctions::Init()
|
|||
Register("mem", [](char* dest, size_t destCount, int argc, char* argv[], duint addr, void* userdata)
|
||||
{
|
||||
duint size;
|
||||
if(argc < 2 || !valfromstring(argv[1], &size) || size > 128)
|
||||
return false;
|
||||
if(argc < 2 || !valfromstring(argv[1], &size))
|
||||
{
|
||||
strcpy_s(dest, destCount, "Invalid argument...");
|
||||
return FORMAT_ERROR_MESSAGE;
|
||||
}
|
||||
if(size > 1024 * 1024 * 10) //10mb max
|
||||
{
|
||||
strcpy_s(dest, destCount, "Too much data (10mb max)...");
|
||||
return FORMAT_ERROR_MESSAGE;
|
||||
}
|
||||
std::vector<unsigned char> data(size);
|
||||
if(!MemRead(addr, data.data(), data.size()))
|
||||
return false;
|
||||
strncpy_s(dest, destCount, StringUtils::ToHex(data.data(), data.size()).c_str(), _TRUNCATE);
|
||||
return true;
|
||||
{
|
||||
strcpy_s(dest, destCount, "Failed to read memory...");
|
||||
return FORMAT_ERROR_MESSAGE;
|
||||
}
|
||||
auto result = StringUtils::ToHex(data.data(), data.size());
|
||||
if(result.size() > destCount)
|
||||
return FORMAT_BUFFER_TOO_SMALL;
|
||||
strcpy_s(dest, destCount, result.c_str());
|
||||
return FORMAT_SUCCESS;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -66,11 +80,21 @@ bool FormatFunctions::Call(std::vector<char> & dest, const String & type, std::v
|
|||
auto found = mFunctions.find(type);
|
||||
if(found == mFunctions.end())
|
||||
return false;
|
||||
|
||||
std::vector<char*> argvn(argv.size());
|
||||
for(size_t i = 0; i < argv.size(); i++)
|
||||
argvn[i] = (char*)argv[i].c_str();
|
||||
|
||||
const auto & f = found->second;
|
||||
return f.cbFunction(dest.data(), dest.size(), int(argv.size()), argvn.data(), value, f.userdata);
|
||||
dest.resize(512, '\0');
|
||||
fuckthis:
|
||||
auto result = f.cbFunction(dest.data(), dest.size() - 1, int(argv.size()), argvn.data(), value, f.userdata);
|
||||
if(result == FORMAT_BUFFER_TOO_SMALL)
|
||||
{
|
||||
dest.resize(dest.size() * 2, '\0');
|
||||
goto fuckthis;
|
||||
}
|
||||
return result != FORMAT_ERROR;
|
||||
}
|
||||
|
||||
bool FormatFunctions::isValidName(const String & name)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
class FormatFunctions
|
||||
{
|
||||
public:
|
||||
using CBFORMATFUNCTION = std::function<bool(char* dest, size_t destCount, int argc, char* argv[], duint value, void* userdata)>;
|
||||
using CBFORMATFUNCTION = std::function<FORMATRESULT(char* dest, size_t destCount, int argc, char* argv[], duint value, void* userdata)>;
|
||||
|
||||
static void Init();
|
||||
static bool Register(const String & type, const CBFORMATFUNCTION & cbFunction, void* userdata = nullptr);
|
||||
|
|
|
@ -219,7 +219,7 @@ static String printComplexValue(FormatValueType value, const String & complexArg
|
|||
duint valuint;
|
||||
if(!split.empty() && valfromstring(value, &valuint))
|
||||
{
|
||||
std::vector<char> dest(MAX_SETTING_SIZE, '\0'); //TODO: check performance, could be made static
|
||||
std::vector<char> dest;
|
||||
if(FormatFunctions::Call(dest, split[0], split, valuint))
|
||||
return String(dest.data());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue