BlockGuardOs.open

This is an expanded version of the hook by the same name published by M66B. It should be used instead of the M66B hook as it is less prone to crash apps. Blocks file access to any but a whitelist of acceptable directories. This should prevent apps from accessing any files outside of app-specific directories. The whitelist consists of (some paths are computed dynamically and will change from a device or Android version to an other): /data/data/<app-id> /data/app/<app-id>-* /data/app/com.android.chrome-* /data/app/com.android.webview-* /data/app/com.google.android.gms-* /data/app/com.google.android.webview-* /data/app/com.google.ar.core-* /data/media/<user-id>/Android/data/<app-id> /data/media/<user-id>/Android/media/<app-id> /data/media/<user-id>/Android/obb/<app-id> /data/misc/ /data/user/<user-id>/<app-id> /data/user_de/<user-id>/<app-id> /data/user_de/<user-id>/com.google.android.gms /dev/ /etc/timezone /proc/<pid>/ /proc/self/ /proc/vmstat /proc/zoneinfo /system/ /vendor/ Changelog: v10 - 2019-07-20 - Allow /data/app/com.google.ar.core-* for ARCore integration in other apps (eg. Maps). v9 - 2019-07-04 - Allow access to /data/app/com.android.webview-* for Bromite. v8 - 2019-04-20 - Allow access to /proc/vmstat, fixes Messenger. v7 - 2019-04-17 - Allow access to /proc/self/ and /proc/<pid>/ (only for the app own pid), fixes FB. v6 - 2019-03-29 - Allow access to /proc/zoneinfo (for eg. Inst*gr*m).

CollectionFif
GroupPublic.Storage
NameBlockGuardOs.open
AuthorM66B, Fif_
Version10
Updated (UTC)2019-07-20 16:25:23
Created (UTC)2018-02-20 22:45:15
Downloads2493
Class namelibcore.io.BlockGuardOs
Method nameopen
Parameter typesjava.lang.String, int, int
Return typejava.io.FileDescriptor
Min SDK1
Max SDK999
Min APK0
Max APK2147483647
Excluded packages-
EnabledYes
OptionalNo
UsageYes
NotifyNo
Settings-
-- Fif.BlockGuardOs.open is a Lua hook definition designed to work                     
-- with XPrivacyLua.

-- Fif.BlockGuardOs.open is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.

-- Fif.BlockGuardOs.open is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.

-- You should have received a copy of the GNU General Public License
-- along with XPrivacyLua.  If not, see <http://www.gnu.org/licenses/>.

-- Copyright 2017-2018 Marcel Bokhorst (M66B)
-- Copyright (C) 2018-2019 Philippe Troin (Fif_ on XDA)

function before(hook, param)
    local context = param:getApplicationContext()
    local WhitelistPrefixes = param:getValue('Fif.BlockGuardOs.open.WhitelistPrefixes', context)

    if WhitelistPrefixes == nil then
        local ai = context:getApplicationInfo()
        local clsFile = luajava.bindClass('java.io.File')
        local clsEnvironment = luajava.bindClass('android.os.Environment')
        local packageName = context:getPackageName()
        local pkgSourceDir = luajava.new(clsFile, ai.sourceDir):getParent()
        local allSourceDir = luajava.new(clsFile, pkgSourceDir):getParent()

        WhitelistPrefixes = {
            '/data/data/' .. packageName .. '/',
            ai.dataDir .. '/',
            pkgSourceDir .. '/',
            allSourceDir .. '/com.google.android.gms-',
            allSourceDir .. '/com.google.android.webview-',
            allSourceDir .. '/com.android.webview-',
            allSourceDir .. '/com.android.chrome-',
            allSourceDir .. '/com.google.ar.core-',
            '/system/',
            '/vendor/',
            '/data/misc/',
            '/etc/timezone',
            '/dev/',
            luajava.new(clsFile, "/proc/self"):getCanonicalPath() .. '/',
            '/proc/self/',
            '/proc/vmstat',
            '/proc/zoneinfo',
        }

        if ai.deviceProtectedDataDir ~= nil then
            table.insert(WhitelistPrefixes, ai.deviceProtectedDataDir .. '/')
            table.insert(WhitelistPrefixes, luajava.new(clsFile,  ai.deviceProtectedDataDir):getParent() .. '/com.google.android.gms/')
        end

        local clsArray = luajava.bindClass('java.lang.reflect.Array')
        local pathJarray = clsEnvironment:buildExternalStorageAppFilesDirs(packageName)
        local i
        for i = 0, pathJarray.length-1 do
            table.insert(WhitelistPrefixes, clsArray:get(pathJarray, i):getParent() .. '/')
        end

        pathJarray = clsEnvironment:buildExternalStorageAppMediaDirs(packageName)
        for i = 0, pathJarray.length-1 do
            table.insert(WhitelistPrefixes, clsArray:get(pathJarray, i):getAbsolutePath() .. '/')
        end

        pathJarray = clsEnvironment:buildExternalStorageAppObbDirs(packageName)
        for i = 0, pathJarray.length-1 do
            table.insert(WhitelistPrefixes, clsArray:get(pathJarray, i):getAbsolutePath() .. '/')
        end

        param:putValue('Fif.BlockGuardOs.open.WhitelistPrefixes', WhitelistPrefixes, context)
        log('WhitelistPrefixes: ' .. table.concat(WhitelistPrefixes, ', '))
    end

    local found = false
    local path = param:getArgument(0)
    if path == nil then
        found = true
    else
        local idx, prefix
        for idx, prefix in pairs(WhitelistPrefixes) do
            if string.sub(path, 1, string.len(prefix)) == prefix then
                found = true
                break
            end
        end
    end

    if found then
        log('Allow ' .. path)
        return false
    else
        log('Deny ' .. path)
        local clsFileNotFound = luajava.bindClass('java.io.FileNotFoundException')
        local fake = luajava.new(clsFileNotFound, path)
        param:setResult(fake)
        return true, path
    end
end