AdHole is proprietary, free-of-charge software. Its source code is not provided, and the program may not be redistributed. The terms of use are in CGU.md (English translation: CGU.en.md).
The program nevertheless relies on libraries written by others, published under permissive open-source licences. All of them allow their use in closed-source software, free or paid. All of them, except those placed in the public domain, require in return that their text and their author's copyright notice accompany the distributed program.
That is why the installer places the file LICENCES-TIERCES.txt next to the program. It
contains the full text of each licence, copied from the file shipped by each project. This file is
not decorative: it is the consideration for these licences. Do not delete it, do not remove it
from the installer.
Modules obtained with go version -m bin/adhole.exe, licences read from the file shipped by each
project. Checked on 13 September 2026.
| Component | Role | Licence |
|---|---|---|
| Go — standard library and runtime | the language itself, compiled into the program | BSD 3-Clause |
| golang.org/x/crypto, exp, net, sys, text | official Go libraries | BSD 3-Clause (identical text) |
| Public Suffix List (via golang.org/x/net/publicsuffix) | knowing where a domain name ends | MPL-2.0 |
| WebView2Loader.dll (Microsoft) | loader for the WebView2 component, embedded in the binary | BSD 3-Clause |
| github.com/jchv/go-webview2 | the dashboard's application window | MIT |
| github.com/jchv/go-winloader | in-memory loading of the WebView2 component | ISC |
| github.com/AdguardTeam/dnsproxy | encrypted DNS resolvers | Apache-2.0 |
| github.com/AdguardTeam/dnscrypt | DNSCrypt protocol | Unlicense |
| github.com/AdguardTeam/golibs | AdGuard utilities | Unlicense |
| github.com/ameshkov/dnsstamps | resolver addresses | Unlicense |
| github.com/miekg/dns | DNS protocol | BSD 3-Clause |
| github.com/elazarl/goproxy | decrypting HTTP(S) proxy | BSD 3-Clause |
| github.com/quic-go/quic-go | QUIC transport (DNS-over-QUIC, HTTP/3) | MIT |
| github.com/quic-go/qpack | HTTP/3 header compression | MIT |
| github.com/robfig/cron | internal scheduling | MIT |
| gopkg.in/yaml.v3 | reading the configuration | MIT and Apache-2.0 |
None of these licences requires AdHole's code to be published.
Two components deserve one more sentence.
The Public Suffix List is the only component under a Mozilla licence. Its data is compiled into
the program to know that lemonde.fr is a domain and co.uk a suffix. The MPL-2.0 allows
distribution in binary form under proprietary terms, provided that you indicate where to obtain its
source form: this is done in LICENCES-TIERCES.txt, which points to
https://publicsuffix.org/list/public_suffix_list.dat.
WebView2Loader.dll is a Microsoft component, redistributed under the BSD 3-Clause licence and
compiled into the binary by the go-webview2 library. The WebView2 engine itself is not
distributed with AdHole: it is part of Windows, or is installed separately from Microsoft.
The tools used to build the program and its installer — Inno Setup, goversioninfo, garble — are not
linked into the executables. Their licences are nevertheless included in LICENCES-TIERCES.txt.
The filtering engines are written for this project
The three engines that decide what is blocked are AdHole's own:
internal/dnsfilter— the whole-home DNS filter;internal/filtre/reseau— the network rules applied to web pages;internal/filtre/cosmetique— hiding the ad slots.
They interpret lists in the AdGuard / EasyList format, a format that these lists publish and that any program can read. A syntax and a file format are not protected by copyright. No code from another blocker is reused.
Filter lists
On a computer (Windows, macOS, Linux), they are not included in the program. It downloads them from their authors' servers, on the user's machine, at first start, then refreshes them every 24 hours.
The Android app contains a copy of the three default DNS lists, so that it filters from the first launch without waiting for a download. Each copy is byte-for-byte identical to the file published by its author; the app replaces it with the published version as soon as it downloads the list again. The iPhone app contains none of them: its DNS filter runs on the publisher's server, which downloads the lists itself.
The iPhone app also ships the rules of its two Safari blockers. These are not copies of lists
but derived files: AdHole translates two lists into Safari's declarative format, and it is those
translations that are shipped, so that Safari filters as soon as the user switches the blockers on.
Those two lists are under a Creative Commons licence, which allows a derived work to be
redistributed; no GPL list is translated before it reaches the device. Details:
LICENCES-TIERCES.txt, section 17, and mobile/SAFARI.md.
Either way, the lists remain the property of their authors.
| List | Author | Engine | Copy in the mobile apps | Stated licence |
|---|---|---|---|---|
| AdGuard DNS filter | AdGuard | DNS | Android only | GPL-3.0 |
| HaGeZi's Multi PRO | hagezi | DNS | Android only | GPL-3.0 |
| HaGeZi's Encrypted DNS Bypass | hagezi | DNS | Android only | GPL-3.0 |
| AdGuard Base filter | AdGuard | proxy (desktop only) | no | GPL-3.0 |
| AdGuard Tracking Protection filter | AdGuard | proxy (desktop only) | no | GPL-3.0 |
| AdGuard French filter | AdGuard | proxy (desktop only) | no | GPL-3.0 |
| EasyList | The EasyList authors | Safari (iPhone) | yes, translated | CC BY-SA 3.0 (or GPL-3.0, at your option) |
| Easylist Cookie List | The EasyList authors | Safari (iPhone) | yes, translated | CC BY 3.0 |
| AdGuard Base filter | AdGuard | Safari (iPhone) | no | GPL-3.0 |
| AdGuard French filter | AdGuard | Safari (iPhone) | no | GPL-3.0 |
| AdGuard Cookie Notices filter | AdGuard | Safari (iPhone) | no | GPL-3.0 |
The titles and licences are those stated in the header of each file. AdGuard describes its base filter as "EasyList + AdGuard English filter": work from EasyList is included in it, under AdGuard's licence. Its DNS filter is also built from other lists (EasyList, EasyPrivacy…), named in its header.
The GPL v3 only imposes its conditions on whoever conveys a copy (section 2: "You may make, run and propagate covered works that you do not convey, without conditions").
- On a computer, AdHole conveys none: the download starts from the user's machine and goes straight to the list's author.
- The Android app does convey one. It therefore meets section 4 of the GPL v3 (verbatim
copies): unchanged copy, headers and licence notices kept, authors named, full licence text
shipped with the app. As a precaution it also meets section 6, in case a compressed copy were
seen as a "non-source form": the source address, the version history and the exact version of
each copy are given. All of this is in
LICENCES-TIERCES.txt(section 16 and appendix B), which the app displays. - The iPhone app conveys none: it contains none of these lists.
- These lists and AdHole form an aggregate within the meaning of section 5: the engine reads them as data, exactly like a list the user adds, and works without them. Their licence applies to them, not to the program. AdHole's terms of use restrict none of the rights the GPL v3 grants on these lists.
Rules not to break, because they are what maintains this situation:
- never embed a copy of a list in the desktop installer, nor serve it again from a server of ours;
- never ship, inside an app, Safari rules derived from a GPL list. Translating a list makes a
derived work of it: shipping that translation would be conveying it, with everything the GPL v3
attaches to conveying.
tools/safari-baseonly reads the Creative Commons lists (internal/filtre/safari/sources.go, fieldEmbarquee); AdGuard's lists are translated on the user's device only, and their translation never leaves it; - never alter the copies shipped in the Android app: they must stay identical to the author's
file.
go generate ./mobileregenerates them and updates the "Copie" line of section 16 ofLICENCES-TIERCES.txt; it stops if an embedded list is not described there, and a test of the mobile engine fails if the section no longer matches the copies; - never refresh more often than the frequency announced by each list in its header
(
! Expires:— 8 hours for hagezi, 12 hours for AdGuard). The current pace, 24 hours, is slower than both.
Removing a list from the configuration leaves the program working, with fewer rules.
What is written here, and nowhere else
Two places in the code speak the same language as existing open-source projects, without reusing their code.
The scriptlet runner (internal/filtre/pages/scriptlets.js) recognises the names and the
semantics of AdGuard scriptlets — set-cookie, abort-on-property-read, remove-class… — so
that the rules of the public lists can be interpreted. A function name and a syntax are not
protected by copyright; the implementation is the project's own, and has neither the form nor the
helper functions of AdGuard's library.
It deliberately departs from it on one point: it refuses to run a rule that would record a positive consent or click "accept". Several public lists contain such rules. AdHole refuses trackers, it does not accept them on your behalf.
The removal of YouTube ads is inspired by open-source projects, whose mechanisms were understood and then rewritten:
- webosbrew/youtube-webos — removing the ad fields from the player's responses, and adding a field to the outgoing request to avoid the punitive wait known as "fake buffering".
- uBlockOrigin/uAssets — analysis of this wait and of the related filter rules.
- TizenTube — the same approach on the TV side.
These three projects are under the GPL. Not one line of their code is reused here: not their
structure, not their functions, not their comments. What is common comes down to the field names
of the YouTube API (adPlacements, adSlots, playerAds…), which are Google's, not theirs.