首页 时政热点 科技头条 智能AI 安全攻防 数码硬件 开发者生态 汽车 游戏 社会热点 开源推荐 医疗健康 归档 标签 关于

可查询的可执行文件

2026-08-26 1 阅读 约8分钟阅读 rguiscard
分享:
字号:
我很惊喜也很高兴地看到我的文章“你的可执行文件是一个 SQLite 数据库”引起了人们的共鸣。我已经考虑这种格式有一段时间了,这个想法似乎引起了其他人的共鸣。快速回顾一下:SELF,一种程序是 SQLite 数据库的格式。我们可以使用 binfmt_misc 触发一个自定义解释器,该解释器映射段表中的行并跳转到入口点,然后一整类二进制工具会分解为 SQL。令我惊讶的是,文件格式为 SQLite 数据库如何不断将所有内容压缩为 SQL。通过评论,我和其他人立即明白了一个想法:如果可执行文件是一个数据库,并且数据库是您可以写入的内容,那么正在运行的程序是否可以使用它来存储其状态? 🤔 是的! 🤯 我们不仅可以将完整的发行版折叠起来,还可以将每个应用程序的所有状态折叠到一个文件中,从而减轻对 /var/ 或 /tmp/ 或 /home/ 或任何其他文件系统的需求。程序可以将其自己的状态存储在运行它的同一文件中,并且可以通过事务方式执行此操作。 self-httpd 是一个概念验证的网络服务器,它正是这样做的。它是从数据库执行的单个文件程序。该文件包含程序、网站、路线和所有访客日志。所有状态都在与程序本身相同的 SQLite 文件中更新。 # 我们的服务器是一个文件,它是一个 SQLite 数据库 $ 文件服务器服务器:SQLite 3.x 数据库,应用程序 id 1397050438,... $ ./server --journal wal 8080 self-httpd:从 /srv/self/server 提供 3 条路由 self-httpd:用 4 个工作人员监听 http://0.0.0.0:8080 $curl -s localhost:8080 | head -1 # 还没有人按下该页面上的按钮 $ sqlite3 server 'SELECT count(*) FROM Presses' 0 $ curl -s -X POST -d press localhost:8080/api/press {"presses":1,"button":"press"} # 应用程序数据位于同一个数据库中 $ sqlite3 server 'SELECT id, at, button FROM Presses' 1|2026-08-25 03:11:28|press # 最初获取页面的 GET 也是如此 $ sqlite3 server 'SELECT count(*) AS n, path FROM attempts GROUP BY path' 1|/ 1|/api/press 此网络服务器位于 https://selfdb.exe.xyz 。 1 1 如果该网站不适合您,抱歉。我将其部署在他们最小的层上。我附上了该网站的屏幕截图,以防万一后代!它是一个文件,一个SQLite数据库,同时它也是服务器。它是网站,它是程序,它是访问者日志和状态。 § 一切都是我的恶魔缪斯 我对 Justine Tunney 的工作非常钦佩,他的现有技术 redbean :单个文件中的网络服务器,构建为具有自解压 ZIP 存档的实际可移植可执行文件,激发了这个想法。自我在很多方面都不那么出色。它依赖于更简单的工具来实现非常相似的东西,但令我惊讶的是,有多少内容会分解为一个域:SQL。然而,redbean 需要包含存档格式(ZIP),而数据库本身就是容器。 Redbean 提供 Lua 挂钩来操作响应,而 SELF 中的等效项是处理程序表中的新行。 INSERT INTO handlers VALUES ( '/api/busiest' , 'SELECT path, count(*) FROM 访问 GROUP BY 路径 ORDER BY 2 DESC LIMIT 5' );如果redbean是一个实际可移植的可执行文件,那么这是一个实际可查询的可执行文件。其中一个可以在任何地方运行,另一个您可以从中选择。 § 您所需要的只是 argv[0] 进程如何访问自身? 🤔 目前,您无法使用 /proc/self/exe 。 2 2 有趣的是,VFS Linux 维护者最近在内核中支持了透明的 binfmt_misc,这将使 /proc/self/exe 指向原始文件。我在这里写过。当 binfmt_misc 匹配时,内核根本不执行你的文件,它执行解释器,并将路径交给它:self-exec 将 argv + 1 传递给程序,因此程序的 argv[0] 是可执行文件本身的路径。解释器还在跳转到入口点之前释放其 SQLite 连接,因此程序可以打开自己的文件并查询它。 int main ( int argc , char ** argv ) { sqlite3 * db ; /* 内核刚刚执行的文件 */ sqlite3_open ( argv [ 0 ], & db ); ...} 这是非常不受限制且神奇的。您可以读取自己的段表或旁边的新表。写入在调用过程中持续存在。 ✨ § self-httpd 我们示例中的网络服务器由三个表组成: 路线 、 访问 和 压力 。我们将记录每一位访客和每一次按下按钮。 -- 添加到可执行文件的内容 -- 编译并链接后 CREATE TABLE 路由(路径 TEXT PRIMARY KEY 、 mime TEXT 、 body BLOB ); -- 站点收集的内容,写回 -- 在运行 CREATE TABLE 访问时写入可执行文件( id INTEGER PRIMARY KEY 、 at TEXT 、 ua TEXT 、 path TEXT );按下创建表(id INTEGER PRIMARY KEY,在 TEXT 处,按钮 TEXT);构建应用程序感觉非常平常且熟悉。我们执行 DDL 来创建应用程序架构并
这篇文章对您有帮助吗?

订阅66必读

每日精选科技资讯,直达你的邮箱