├── .gitattributes ├── .gitignore ├── BlockEmAll.plist ├── LICENSE ├── Makefile ├── README.md ├── Tweak.x ├── control └── layout └── DEBIAN └── postinst /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .theos 2 | packages 3 | .DS_Store -------------------------------------------------------------------------------- /BlockEmAll.plist: -------------------------------------------------------------------------------- 1 | { Filter = { Bundles = ( "com.apple.SafariServices.ContentBlockerLoader" ); }; } 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 - 2024 PoomSmart 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PACKAGE_VERSION = 1.0.1 2 | 3 | TARGET = iphone:clang:latest:9.0 4 | ARCHS = arm64 arm64e 5 | 6 | include $(THEOS)/makefiles/common.mk 7 | 8 | TWEAK_NAME = BlockEmAll 9 | $(TWEAK_NAME)_FILES = Tweak.x 10 | $(TWEAK_NAME)_CFLAGS = -fobjc-arc 11 | 12 | include $(THEOS_MAKE_PATH)/tweak.mk 13 | 14 | 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BlockEmAll 2 | A jailbreak tweak that bypasses 50,000/150,000 content filter rules limit for iOS Safari. 3 | 4 | # Increasing memory limit 5 | As of iOS 9, iOS will kill such processes that consume too much memory. 6 | 7 | Memory usage of processes like Safari content blockers are limited to **12 MB**. This is why we must alter the file storing memory limits: `/System/Library/LaunchDaemons/com.apple.jetsamproperties.XX.plist` where `XX` is your device internal model number. For example `XX` either is `N69` or `N69u` for iPhone SE 1st-generation devices. 8 | 9 | We can increase `ActiveHardMemoryLimit` and `InactiveHardMemoryLimit` in `VersionN -> Extension -> Override -> com.apple.Safari.content-blocker` (`N` is some number) to, says, **256 MB**. Doing so allows content blockers like Adguard Pro to add ten thousands of filters with no errors. 10 | However, it will complain again when the rules exceed 50,000 (or 150,000) entries, as iOS refuses to compile any rules of size over that limit. We need more work. 11 | 12 | # Compromising WebCore's limitation 13 | Apple hardcoded the limit in their open-source WebCore implementation which can be founded [here](https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/contentextensions/ContentExtensionParser.cpp). In a function called `Expected, std::error_code> loadEncodedRules(ExecState& exec, const String& ruleJSON)`, filter rules are in form of an encoded string, being parsed as a JSON array. 14 | It raises an error `ContentExtensionError::JSONTooManyRules` when the array length exceeds `maxRuleCount = 50000 or 150000`. 15 | 16 | Hooking into this pure C++ function is *uneasy*, but there's an alternative *smart* approach; we can hook a higher level Objective-C API: `-[WKContentRuleListStore (_)compileContentRuleListForIdentifier:encodedContentRuleList:completionHandler:]`, and [here](https://trac.webkit.org/browser/webkit/trunk/Source/WebKit/UIProcess/API/Cocoa/WKContentRuleListStore.mm) is where it is located. 17 | This method compiles the rules by calling a lower level API, given the content blocker identifier and some action to be done after the compilation has been done. Eventually, this method will invoke the `loadEncodedRules()` function. 18 | We cannot input more than 50,000/150,000 rules at a time, but we can input no more than 50,000/150,000 rules multiple times. In other words, **you can seperate the rules into chunks that each one is no more than 50,000/150,000 entries**. 19 | 20 | In terms of pseudocode: 21 | ``` 22 | compile(identifier, ruleList, completion): 23 | count = ruleList.count 24 | j = 0 25 | while count > 0: 26 | range = (j, min(50000, count)) // 50000 for backward compatibility 27 | subruleList = subarray(ruleList, range) 28 | original_compile(identifier, subruleList, completion) 29 | j += range.length 30 | count -= range.length 31 | ``` 32 | 33 | # Increasing memory limit (again) 34 | That Objective-C method is invoked in a XPC service dedicated for loading rules from user-installed content blockers. Similarly, there is a memory limit which this process should never exceed. 35 | 36 | Found in `VersionN -> XPCService -> Override -> com.apple.SafariServices.ContentBlockerLoader`, we can set both `ActiveSoftMemoryLimit` and `InactiveHardMemoryLimit` to something higher, like **512 MB** that seems to be enough. Of course, you need to check how much RAM your device can offer. 37 | 38 | Changes to increasing memory limit **require a reboot**. 39 | 40 | # Per-app limitation bypassing 41 | Usually, content blockers (Adguard Pro included) will both limit the total rules to 50,000 and warn users about that. One must find and hook method(s) that limit the number, and the rest would work as intended. 42 | 43 | Ensuring all four sections and **reenabling the content blockers that you are using**, you are set. And for your information, BlockEmAll 0.0.2+ will do the memory limit increasing automatically, though without rolling back when uninstalling - as it is way harmless. 44 | -------------------------------------------------------------------------------- /Tweak.x: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #define PROCEDURES1 \ 4 | NSError *error = nil; \ 5 | NSArray *rules = [NSJSONSerialization JSONObjectWithData:[encodedContentRuleList dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error]; \ 6 | if (!error) { \ 7 | int itemsRemaining = rules.count; \ 8 | int j = 0; \ 9 | while (itemsRemaining) { \ 10 | NSRange range = NSMakeRange(j, MIN(50000, itemsRemaining)); \ 11 | NSMutableArray *subrules = [NSMutableArray array]; \ 12 | [subrules addObjectsFromArray:[rules subarrayWithRange:range]]; \ 13 | NSData *subrulesJSON = [NSJSONSerialization dataWithJSONObject:subrules options:NSJSONWritingPrettyPrinted error:&error]; \ 14 | if (!error) { \ 15 | NSString *encodedSubrules = [[NSString alloc] initWithData:subrulesJSON encoding:NSUTF8StringEncoding]; 16 | #define PROCEDURES2 \ 17 | itemsRemaining -= range.length; \ 18 | j += range.length; \ 19 | } \ 20 | subrules = nil; \ 21 | subrulesJSON = nil; \ 22 | } \ 23 | } 24 | 25 | %hook WKContentRuleListStore 26 | 27 | - (void)compileContentRuleListForIdentifier:(NSString *)identifier encodedContentRuleList:(NSString *)encodedContentRuleList completionHandler:(void (^)(void **, NSError *))completionHandler { 28 | PROCEDURES1 29 | %orig(identifier, encodedSubrules, completionHandler); 30 | PROCEDURES2 31 | } 32 | 33 | - (void)_compileContentRuleListForIdentifier:(NSString *)identifier encodedContentRuleList:(NS_RELEASES_ARGUMENT NSString *)encodedContentRuleList completionHandler:(void (^)(void **, NSError *))completionHandler { 34 | PROCEDURES1 35 | %orig(identifier, encodedSubrules, completionHandler); 36 | PROCEDURES2 37 | } 38 | 39 | %end 40 | -------------------------------------------------------------------------------- /control: -------------------------------------------------------------------------------- 1 | Package: com.ps.blockemall 2 | Name: BlockEmAll 3 | Depends: firmware (>= 9.0), firmware (<< 15.0), mobilesubstrate, com.bingner.plutil, system-cmds 4 | Version: 1.0.0 5 | Architecture: iphoneos-arm 6 | Description: No 50,000 entries limit for Safari content blockers. 7 | Maintainer: PoomSmart 8 | Author: PoomSmart 9 | Section: Tweaks 10 | -------------------------------------------------------------------------------- /layout/DEBIAN/postinst: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | model=$(sysctl -n hw.targettype) 4 | 5 | jetsam_plist="/System/Library/LaunchDaemons/com.apple.jetsamproperties.${model}.plist" 6 | 7 | if [[ ! -f "${jetsam_plist}" ]];then 8 | echo "Error: Couldn't find the jetsam properties plist (${jetsam_plist})" 9 | exit 1 10 | fi 11 | 12 | # The new upper memory limit for com.apple.Safari.content-blocker 13 | new_limit=256 14 | 15 | plutil -key Version4 -key Extension -key Override -key com.apple.Safari.content-blocker -key ActiveHardMemoryLimit -value ${new_limit} $jetsam_plist 16 | plutil -key Version4 -key Extension -key Override -key com.apple.Safari.content-blocker -key InactiveHardMemoryLimit -value ${new_limit} $jetsam_plist 17 | 18 | # The new upper memory limit for com.apple.SafariServices.ContentBlockerLoader 19 | new_limit=384 20 | 21 | plutil -key Version4 -key XPCService -key Override -key com.apple.SafariServices.ContentBlockerLoader -key ActiveSoftMemoryLimit -value ${new_limit} $jetsam_plist 22 | plutil -key Version4 -key XPCService -key Override -key com.apple.SafariServices.ContentBlockerLoader -key InactiveHardMemoryLimit -value ${new_limit} $jetsam_plist 23 | 24 | echo "A reboot or ldrestart IS REQUIRED for the memory limit change to take effects" --------------------------------------------------------------------------------