local _ident = 0
function ident()
_ident = _ident + 1
end
function deent()
_ident = _ident - 1
end
function bprint(smth)
local buf = ""
for i = 1, _ident do
buf = buf .. ". "
end
buf = buf .. smth
print(buf)
end
function remove_prefix(str, prefix)
if str:sub(1, #prefix) == prefix then
return str:sub(#prefix + 1), true
end
return str, false
end
function remove_suffix(str, suffix)
if str:sub(- #suffix) == suffix then
return str:sub(1, - #suffix - 1), true
end
return str, false
end
function choose_prefix(str, prefixes)
for _, prefix in ipairs(prefixes) do
if str:sub(1, #prefix) == prefix then
return str:sub(#prefix + 1), prefix
end
end
error("Unexpected function name")
end
function OnBeforeCompilation()
bprint("OnBeforeCompilation")
ident()
local file = vmprotect.core():outputArchitecture()
local mapFunctions = file:mapFunctions()
for i = 1, mapFunctions:count() do
local fn = mapFunctions:item(i)
if fn:type() ~= ObjectType.Code then
goto continue
end
local name = fn:name()
local protinfo = name:match("VMPROTECT_MARKER_(.-)_END")
if protinfo == nil then
goto continue
end
local processing_kind
local lock_to_key
protinfo, processing_kind = choose_prefix(protinfo, { "ultra", "virtualize", "mutate", "destroy" })
protinfo, lock_to_key = remove_prefix(protinfo, "_lock")
bprint("Processing " .. name .. " (" .. fn:address():tostring() .. ")")
ident()
local addType
if processing_kind == "ultra" then
bprint("Mutating + virtualizing")
addType = CompilationType.Ultra
elseif processing_kind == "virtualize" then
bprint("Virtualizing")
addType = CompilationType.Virtualization
elseif processing_kind == "mutate" then
bprint("Mutating")
addType = CompilationType.Mutation
elseif processing_kind == "destroy" then
bprint("Destroying")
addType = nil
end
local added = file:functions():addByAddress(fn:address(), addType)
if processing_kind == "destroy" then
added:destroy()
end
if lock_to_key then
if addType ~= CompilationType.Virtualization and addType ~= CompilationType.Ultra then
error("Lock requires virtualization")
end
bprint("And locking by key")
added:setLockToKey(true)
end
deent()
::continue::
end
deent()
end