_G.debug.getinfo = detours:Add(_G.debug.getinfo, function(func_or_level, fields)
    if isfunction(func_or_level) and detours.detours_to_original[func_or_level] then
        func_or_level = detours.detours_to_original[func_or_level]
    elseif isnumber(func_or_level) then
        -- bad idea? idk
        -- see if bad behavior against lua
        if func_or_level == 0 then
            func_or_level = 1 end

        func_or_level = func_or_level + 1
    end

    local info = fnOriginal(func_or_level, fields)
    if detours.detours_to_original[info.func] then
        info.func = detours.detours_to_original[info.func] end

    return info
end)

_G.debug.getfenv = detours:Add(_G.debug.getfenv, function(obj)
    return fnOriginal(obj)
    -- getfenv on our stored detour functions
    --if detours.detours_to_original[obj] then
    --	return _G
    --end
    --
    --local fenv = fnOriginal(obj)
    --
    --if detours:IsSubstitutingObject(fenv) then
    --	return detours:GetObjectSubstitute(obj)
    --end
    --
    --return fenv
end)
_G.debug.setfenv = detours:Add(_G.setfenv, function(obj, fenv)
    return fnOriginal(obj, fenv)
end)

_G.debug.getupvalue = detours:Add(_G.debug.getupvalue, function(func, upvalue_index)
    if detours.detours_to_original[func] then
        func = detours.detours_to_original[func]
    end

    local upvalName, upvalObject = fnOriginal(func, upvalue_index)

    if detours:IsSubstitutingObject(upvalObject) then
        upvalObject = detours:GetObjectSubstitute(upvalObject)
    end

    return upvalName, upvalObject
end)

local debug_hook, debug_mask, debug_count = nil, "", 0
_G.debug.gethook = detours:Add(_G.debug.gethook, function(a)
    return debug_hook, debug_mask, debug_count
end)
_G.debug.sethook = detours:Add(_G.debug.sethook, function(a,b,c,d)
    if isfunction(a) then
        d = c
        c = b
        b = a
        a = nil
    end

    debug_hook = b
    debug_mask = c
    debug_count = d
    return fnOriginal(a,b,c)
end)

_G.string.dump = detours:Add(string.dump, function(func, stripDebugInfo)
    if G.isfunction(func) and detours.detours_to_original[func] then
        func = detours.detours_to_original[func]
    end

    return fnOriginal(func, stripDebugInfo)
end)

-- error messages

--_G.debug.traceback = detours:Add(debug.traceback, function(thread, strMessage, a)
--    print("traceback", thread, strMessage, a)
--
--    return fnOriginal(thread, strMessage, a)
--end)

--[[
_R[1] = detours:Add(_R[1], function(strError)
    for i = 2, math.huge do
        local info = debug.getinfo(i)
        if not info then break end

        print("_R[1]", i, info.short_src, info.name, info.func)
    end

    local ret = fnOriginal(strError)
    --print("_r", ret)

    return ret
    --return fnOriginal(strError)
end)
]]