C is 0-based, while Lua is 1-based. Thus if I do "for i = 1, obj:size() do obj:item(i)..." in Lua, then I'll access an invalid index.
Accessing an invalid index crashes VMP, so e.g. vmprotect.core():inputFile():item(100):functions()
I think there should be a check there that throws a Lua error in that case.
Aside from that it'd be really convenient to access everything 1-based, like in other Lua scripts.
The next thing is that the overall data access is a bit inconvenient. So to print the name of the input file I have to write
Code: Select all
print(vmprotect.core():inputFile():name())
Code: Select all
print(vmprotect.core.inputFile.name)
Code: Select all
local WrapUserdata
local Meta = {
__index = function(_t, _k)
local func = _t.__UD[_k]
assert(func, k)
local result = func(_t.__UD)
if type(result) == "userdata" then
return WrapUserdata(result)
else
return result
end
end,
__newindex = function()
error("Please don't write to the API tables")
end
}
function WrapUserdata(_UD)
local t = {__UD = _UD}
setmetatable(t, Meta)
return t
end
local _vmprotect = WrapUserdata(vmprotect)
print(_vmprotect.core.inputFile.name)
This wrapper i.e. doesn't work with array access, so I can't do
Code: Select all
vmprotect.core.inputFile.item[1].functions
Code: Select all
for i, file in ipairs(vmprotect.core.inputFile.item) do
Currently the returned userdata only has a metatable that supports calling functions.
Aside from that I also have a general usage question. I don't need code for that, but would just like to know if this is the way to do it.
Let's assume I want to automatically add all functions that have "_secure" in their name and have a length >= 5 byte.
Everything that can be accessed via mapFunctions has a size of 0, at least if it's a function.
So I'll have to add all functions in the mapFile to the project (if they fit the name pattern), and then traverse the list of added functions. Only then I can get the size of the function, xrefs, etc. So if it doesn't fit I'll have to remove it. I guess there's some overhead in case I intend to do something like that with 10000+ functions that need to be checked?
Btw: Where did VMProtector.AddByAddress() go?
Last but not least I have a suggestion which might be a really nice killer feature. It requires some time to be added, even though some features of the existing mutation engine can probably be re-used: The list of instructions in the added function list is currently read only. It'd be great to be able to modify those instructions and to even insert new instructions (without breaking relative jumps, jump tables, etc of course). That way it'd be possible to have custom mutation add-ins that are executed as a pre-pass.