Web 安全的核心是围绕 “如何保护用户数据与服务端资源” 构建的防御体系,而同源策略、CORS、XSS、CSRF 及 Cookie 安全设置是其中最基础且关键的模块。以下将按 “基础安全策略→跨域机制→攻击手段→防御配置” 的逻辑,从概念定义、核心作用、关联场景三个层级,拆解各模块的核心信息,并明确漏洞职责与执行环境。

第一部分:基础安全基石 —— 同源策略(Same-Origin Policy, SOP)

同源策略是浏览器的默认安全 “防火墙”,是所有 Web 安全机制的基础,其核心目的是 “隔离不同站点的资源,防止恶意站点非法访问合法站点的数据”。

1. 概念与定义

  • 同源的判定标准:两个 URL 需同时满足以下 3 个条件,才被视为 “同源”:
    1. 协议相同(如均为http或均为https);
    2. 域名相同(如均为www.example.comblog.example.comwww.example.com不同源);
    3. 端口相同(如均为 80 端口或均为 443 端口,默认端口可省略)。
  • 核心规则:浏览器仅允许 “同源” 的页面 / 脚本,读取或操作另一个同源页面的资源(如 Cookie、LocalStorage、DOM 元素、AJAX 响应数据);非同源资源默认被 “隔离”,无法直接访问。

2. 核心作用与场景

  • 保护目标:用户的敏感数据(如登录状态、个人信息)和服务端资源。
  • 典型场景
    • 你在www.baidu.com打开的页面,无法通过脚本读取www.taobao.com的 Cookie(否则会直接窃取淘宝登录状态);
    • 本地file://协议打开的 HTML 文件,无法通过 AJAX 请求http://localhost的服务端数据(协议不同源)。

3. 职责与执行环境

  • 执行环境:仅在浏览器端生效(服务端无同源策略限制,需自行做跨域权限控制)。
  • 漏洞关联:同源策略本身是 “防御机制”,无 “漏洞” 属性;但后续的 CSRF 攻击,本质是利用了 “浏览器自动携带同源 Cookie” 这一同源策略的 “特性”(非漏洞),间接绕过身份验证。

第二部分:跨域解决方案 ——CORS(Cross-Origin Resource Sharing)

同源策略虽安全,但无法满足 “合法跨域需求”(如前端项目部署在frontend.example.com,需请求api.example.com的接口)。CORS 是服务端授权、浏览器执行的跨域资源共享机制,用于 “在安全前提下开放跨域权限”。

1. 概念与定义

  • 核心逻辑:当浏览器发起 “非同源” 请求时,会先检查服务端返回的Access-Control-*响应头,若头信息允许当前源的跨域请求,则浏览器放行响应数据;否则拦截数据,抛出跨域错误。

  • 关键响应头(服务端配置):

    响应头 作用说明
    Access-Control-Allow-Origin 允许跨域的源(如https://frontend.example.com*表示允许所有源,不推荐)
    Access-Control-Allow-Methods 允许跨域的 HTTP 方法(如GET, POST, PUT
    Access-Control-Allow-Credentials 是否允许跨域请求携带 Cookie(需设为true,且Allow-Origin不能为*
    Access-Control-Allow-Headers 允许跨域请求携带的自定义请求头(如Content-Type, Token

2. 跨域请求执行流程

  1. 浏览器发起请求:若为 “简单请求”(如GET/POST,请求头无自定义字段),直接发送请求;若为 “复杂请求”(如PUT/DELETE、带自定义头),先发送预检请求(OPTIONS),询问服务端是否允许跨域。

  2. 服务端响应:返回业务数据的同时,附带Access-Control-*头。

  3. 浏览器过滤:根据 “同源策略 + 服务端 CORS 头” 判断:

    • 若 CORS 头允许当前源,则放行数据,前端可正常使用;

    • 若 CORS 头不允许或未配置,则拦截数据,前端控制台报错 “Access to XMLHttpRequest at … from origin … has been blocked by CORS policy”。

3. 职责与执行环境

  • 执行环境服务端配置 + 浏览器执行(服务端负责 “授权”,浏览器负责 “校验与放行 / 拦截”)。
  • 漏洞职责:若服务端错误配置 CORS(如Allow-Origin设为*且开启Allow-Credentials),可能导致 “恶意站点跨域获取敏感数据”,属于服务端配置漏洞

第三部分:前端注入攻击 ——XSS(Cross-Site Scripting)

XSS 是最常见的 Web 攻击之一,本质是 “攻击者将恶意 JavaScript 脚本注入到目标站点的页面中,由浏览器执行脚本,窃取用户数据或控制页面”。其核心是 “用户输入未被过滤,直接被页面渲染执行”。

1. 概念与定义

  • 核心逻辑:目标站点(前端 / 后端)未对用户输入的内容(如评论、URL 参数、表单数据)做 “转义处理”,导致攻击者输入的<script>等恶意代码,被页面 “原封不动” 地渲染并执行。
  • 攻击目标用户的浏览器环境(脚本在用户本地执行,而非服务端),最终目的是窃取用户敏感数据(如 Cookie、SessionID、账号密码)或执行恶意操作(如伪造用户点击、跳转钓鱼网站)。

2. 三大类型:按漏洞位置与存储方式划分

不同类型的 XSS,其漏洞职责(前端 / 后端)、执行场景完全不同,具体对比如下:

类型 概念定义 漏洞职责 执行环境 典型场景
DOM 型 XSS 漏洞仅存在于前端代码,因前端直接使用document.writeinnerHTML等 API,将未过滤的用户输入(如 URL 参数、LocalStorage 数据)插入 DOM,导致脚本执行。 前端 用户浏览器 前端页面通过location.hash获取 URL 中的#后面的参数,直接用innerHTML插入页面,攻击者构造http://example.com/#<script>窃取Cookie</script>,用户点击后脚本执行。
反射型 XSS 漏洞存在于后端代码,后端将未过滤的用户输入(如 URL 参数、表单提交内容)直接 “反射” 到 HTML 响应中,浏览器渲染时执行脚本。 后端 用户浏览器 搜索功能:后端接收?keyword=xxx,直接在页面中输出 “搜索结果:xxx”,攻击者构造?keyword=<script>窃取Cookie</script>,用户点击该链接后,后端返回的页面包含恶意脚本,浏览器执行。
存储型 XSS 漏洞存在于后端代码,后端将未过滤的用户输入(如评论、留言、头像 URL)存储到数据库,其他用户访问该页面时,后端从数据库读取并输出恶意脚本,浏览器执行。 后端 所有访问该页面的用户浏览器 论坛评论:攻击者发布包含<script>窃取Cookie</script>的评论,后端存储到数据库,其他用户打开该评论页面时,后端将恶意脚本返回,所有用户的浏览器都会执行脚本,批量窃取 Cookie。

3. 核心危害:Cookie 劫持

XSS 的主要危害是 “Cookie 劫持”,流程如下:

  1. 攻击者通过 XSS 注入恶意脚本(如<script>var cookie=document.cookie; 发送到攻击者服务器</script>);
  2. 用户访问被注入的页面,脚本在用户浏览器执行,读取当前站点的 Cookie(包含登录状态);
  3. 脚本通过 AJAX 或图片请求,将 Cookie 发送到攻击者的服务器;
  4. 攻击者拿到 Cookie 后,可伪装成该用户登录目标站点,获取个人信息或执行敏感操作(如转账、改密码)。

第四部分:身份伪造攻击 ——CSRF(Cross-Site Request Forgery,跨站请求伪造)

CSRF 与 XSS 完全不同,其本质是 “利用浏览器自动携带同源 Cookie 的特性,伪造用户身份,在目标站点执行敏感操作”,核心是 “伪造操作而非窃取数据”。

1. 概念与定义

  • 核心逻辑:攻击者构造一个 “目标站点的敏感操作请求”(如转账、改密码、发布评论),诱导用户在 “已登录目标站点” 的情况下,访问攻击者的页面或点击链接,浏览器会自动携带目标站点的 Cookie(因 Cookie 与目标站点同源),从而让服务端误以为是用户本人发起的操作,执行请求。
  • 关键前提:用户必须已登录目标站点(浏览器中存在目标站点的登录 Cookie),否则无法伪造身份。

2. 攻击目标与执行流程

  • 攻击目标服务端的敏感操作(如转账、修改个人信息),而非用户的 Cookie 数据(CSRF 不直接获取 Cookie,仅利用 Cookie 自动携带的特性)。
  • 执行流程(以 “转账” 为例)
    1. 用户登录www.bank.com(银行站点),浏览器保存银行的登录 Cookie;
    2. 用户未退出银行登录,误点击攻击者的钓鱼链接http://attacker.com/evil.html
    3. evil.html中隐藏一个表单或 AJAX 请求,指向银行的转账接口:http://www.bank.com/transfer?to=攻击者账号&money=1000
    4. 浏览器发起该请求时,自动携带www.bank.com的 Cookie(同源特性);
    5. 银行服务端验证 Cookie 有效,误以为是用户本人操作,执行转账。

3. 与 XSS 的核心区别

对比维度 XSS(跨站脚本) CSRF(跨站请求伪造)
核心目的 窃取用户数据(如 Cookie) 伪造用户执行敏感操作(如转账)
脚本执行位置 目标站点的页面中 攻击者的页面中
是否依赖 Cookie 是(最终目的是窃取 Cookie) 是(利用 Cookie 自动携带特性)
漏洞职责 DOM 型(前端)、反射 / 存储型(后端) 后端(未验证请求来源)

第五部分:Cookie 安全配置 —— 防御 XSS 与 CSRF 的关键

Cookie 是用户登录状态的核心载体,XSS 和 CSRF 的攻击均与 Cookie 相关。通过配置 Cookie 的安全属性,可直接降低攻击风险。

1. 三大安全属性详解

属性 作用说明 防御目标 配置示例
HttpOnly 禁止浏览器的 JavaScript 脚本读取 Cookie(document.cookie无法获取),仅允许浏览器在请求时自动携带。 XSS 攻击(无法通过脚本窃取 Cookie) Set-Cookie: sessionId=xxx; HttpOnly
SameSite 限制 Cookie 仅在 “同源请求” 或 “第一方请求” 中携带,禁止第三方站点(如攻击者页面)的请求携带。 CSRF 攻击(第三方请求无法携带 Cookie) Set-Cookie: sessionId=xxx; SameSite=Strict(仅同源请求携带)或SameSite=Lax(部分跨站请求允许,如链接跳转)
Secure 仅允许 Cookie 在HTTPS 协议的请求中携带,HTTP 协议的请求会自动忽略该 Cookie。 防止 Cookie 在 HTTP 传输中被窃听(如中间人攻击) Set-Cookie: sessionId=xxx; Secure

2. 配置建议(组合使用)

生产环境中,应至少组合配置以下 3 个属性,最大化 Cookie 安全性:

1
Set-Cookie: sessionId=abc123; HttpOnly; SameSite=Strict; Secure; Path=/; Domain=example.com
  • Path=/:限制 Cookie 仅在example.com/及其子路径下生效;
  • Domain=example.com:限制 Cookie 仅在example.com及其子域名(如blog.example.com)下生效。

第六部分:CSRF 终极防御 ——CSRF Token

CSRF 攻击的核心漏洞是服务端仅通过 Cookie 验证用户身份,未验证请求的真实来源。而 CSRF Token 是专门针对这一漏洞的后端防御机制,其核心逻辑是 “为每个合法请求绑定一个唯一的、不可预测的令牌,服务端同时验证 Cookie 与 Token,缺一不可”。

1. 概念与定义

  • CSRF Token:是服务端生成的一串随机、唯一、一次性的字符串,用于标识 “当前请求是用户主动在目标站点发起的,而非第三方站点伪造的”。
  • 核心原理
    1. 服务端为每个已登录用户的会话(Session)生成一个唯一的 CSRF Token,并存储在服务端(如 Session 中);
    2. 目标站点的所有敏感操作表单(如转账、改密码),都会在页面渲染时,将 CSRF Token 以隐藏字段、请求头、URL 参数的形式嵌入;
    3. 用户提交表单时,浏览器会同时发送Cookie(身份验证)CSRF Token(请求合法性验证)
    4. 服务端接收到请求后,不仅验证 Cookie 的有效性,还会验证请求中的 Token 是否与服务端存储的 Token 一致;
    5. 若 Token 一致,则认为是合法请求,执行操作;若 Token 不一致或缺失,则拒绝请求。

2. 攻击防御逻辑

CSRF 攻击无法绕过 CSRF Token 验证,原因如下:

  • 攻击者的第三方站点无法获取目标站点的 CSRF Token(同源策略限制:第三方站点的脚本无法读取目标站点页面中的 Token,也无法通过 AJAX 请求获取 Token);
  • 攻击者无法伪造有效的 CSRF Token(Token 是随机生成的,且与用户会话绑定,攻击者无法预测);
  • 即使攻击者诱导用户提交请求,也只能携带 Cookie,无法携带有效的 Token,服务端会直接拒绝。

3. 实现方式与场景

实现方式 概念说明 适用场景 优缺点
表单隐藏字段 服务端在表单中嵌入 <input type="hidden" name="csrfToken" value="xxx">,用户提交表单时,Token 随表单数据一起发送。 传统表单提交(POST 请求) 优点:实现简单,兼容性好;缺点:仅适用于表单提交,无法用于 AJAX 请求。
请求头携带 服务端在页面中渲染 Token(如存储在 meta 标签中),前端 AJAX 请求时,从 meta 标签中读取 Token,添加到自定义请求头(如 X-CSRF-Token: xxx)中发送。 现代 AJAX 请求(GET/POST/PUT/DELETE) 优点:适用于所有请求类型,安全性更高(不易被第三方站点伪造);缺点:需要前端配合处理请求头。
URL 参数携带 服务端在敏感操作的 URL 中添加 Token 参数(如 http://example.com/transfer?csrfToken=xxx&to=xxx&money=xxx)。 简单的 GET 请求(不推荐用于敏感操作) 优点:实现简单;缺点:Token 会出现在 URL 中,可能被日志记录,安全性较低,不推荐用于转账、改密码等敏感操作。

4. 职责与执行环境

  • 执行环境服务端生成 + 前端携带 + 服务端验证(全链路后端主导)。
  • 漏洞职责:若服务端未实现 CSRF Token 验证,或实现不当(如 Token 重复使用、与用户会话不绑定、未验证 Token),则属于服务端漏洞;若前端未正确携带 Token(如 AJAX 请求忘记添加 Token 头),则属于前端配置漏洞,但不会导致 CSRF 攻击,仅会导致合法请求被拒绝。

CSRF Token 与 SameSite Cookie 是互补的防御手段,生产环境中建议同时使用

  • SameSite Cookie 是浏览器端的防御,可阻止第三方站点的请求携带 Cookie,是第一道防线;
  • CSRF Token 是服务端的防御,即使 SameSite Cookie 被绕过(如部分老旧浏览器不支持 SameSite 属性),也能有效防御 CSRF 攻击,是第二道防线。

第七部分:XSS 终极防御 —— 输出过滤(Input Validation & Output Escaping)

XSS 攻击的核心漏洞是用户输入的恶意代码未被过滤,直接被页面渲染执行。输出过滤是针对这一漏洞的核心防御机制,其核心逻辑是 “对所有用户输入进行严格的验证,对所有输出到页面的内容进行适当的转义,确保恶意代码被当作普通文本处理,而非可执行的脚本”。

1. 概念与定义

输出过滤包含两个核心环节,二者缺一不可:

  • 输入验证(Input Validation):在数据进入系统时(前端提交→后端接收),对用户输入的内容进行格式、长度、内容的验证,拒绝不符合规则的输入。例如:手机号必须是 11 位数字,邮箱必须符合邮箱格式,评论内容不能包含特殊标签等。
  • 输出转义(Output Escaping):在数据输出到页面时(后端渲染→前端展示),对要输出的内容进行转义处理,将特殊字符(如 <>"'&)转换为 HTML 实体,使得浏览器将其当作普通文本渲染,而非可执行的 HTML 或 JavaScript 代码。

2. 核心转义规则

HTML 中最常用的特殊字符转义规则如下,这是防御 XSS 的基础:

原始字符 HTML 实体 作用说明
< < 小于号,转义后不会被识别为 HTML 标签的开始(如 <script> 会被转义为 <script>)。
> > 大于号,转义后不会被识别为 HTML 标签的结束。
" " 双引号,转义后不会被识别为 HTML 属性的引号(如 onclick="alert(1)" 会被转义为 onclick="alert(1)")。
' ' 单引号,转义后不会被识别为 HTML 属性的单引号。
& & 和号,转义后不会被识别为 HTML 实体的开始。

示例

  • 攻击者输入的恶意代码:<script>alert('XSS')</script>
  • 经过输出转义后:<script>alert('XSS')</script>
  • 浏览器渲染时,会显示为普通文本 <script>alert('XSS')</script>,而不会执行脚本。

3. 按 XSS 类型的防御策略

输出过滤需要根据不同类型的 XSS 漏洞,采取不同的防御策略,明确前端与后端的职责

(1)存储型 & 反射型 XSS(后端漏洞)—— 后端主导过滤

这两种 XSS 的漏洞都在后端,因此防御的核心是后端,前端仅作为辅助验证。

  • 防御策略
    1. 后端输入验证:接收用户输入时,严格验证输入的格式、内容,拒绝包含恶意标签(如 <script><iframe>)、恶意事件(如 onclickonload)的输入;
    2. 后端输出转义:将数据输出到 HTML 页面时,对所有用户输入的内容进行 HTML 转义处理;
    3. 前端辅助验证:在用户提交数据前,前端先进行一次输入验证(如表单验证),可以减少无效请求,但不能替代后端验证(攻击者可以绕过前端验证,直接向后端发送恶意请求)。
  • 典型场景:论坛评论、搜索结果、用户昵称展示等,后端必须在输出时进行转义。

(2)DOM 型 XSS(前端漏洞)—— 前端主导过滤

DOM 型 XSS 的漏洞在前端,因此防御的核心是前端

  • 防御策略
    1. 前端输入验证:对从 URL 参数、LocalStorage、DOM 中获取的用户输入,进行严格的验证;
    2. 前端输出转义
      • 避免使用危险的 DOM API:如 document.writeinnerHTMLouterHTML,这些 API 会直接将内容作为 HTML 渲染,容易导致 XSS;
      • 使用安全的 DOM API:如 textContent,该 API 会将内容作为普通文本渲染,自动忽略所有 HTML 标签,不会执行脚本;
      • 若必须使用 innerHTML,则需要对输入的内容进行手动转义,将特殊字符转换为 HTML 实体。
  • 典型场景:前端通过 location.hash 获取 URL 参数,然后插入到页面中,应使用 textContent 而非 innerHTML

4. 进阶防御:内容安全策略(CSP)

输出过滤是 XSS 的基础防御,而内容安全策略(Content Security Policy,CSP) 是进阶的补充防御手段,其核心逻辑是 “浏览器通过服务端下发的 CSP 头,限制页面可以加载的资源(如脚本、样式、图片)的来源,禁止执行内联脚本和 eval 函数,从而从根本上阻止 XSS 脚本的执行”。

  • 核心作用:即使输出过滤被绕过,攻击者注入了恶意脚本,CSP 也能阻止脚本的执行。

  • 配置方式:服务端通过响应头 Content-Security-Policy 配置,例如:

    1
    Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self'; img-src 'self' data:;

    该配置的含义是:

    • default-src 'self':默认情况下,仅允许加载同源的资源;
    • script-src 'self' https://cdn.example.com:仅允许加载同源的脚本,以及 https://cdn.example.com 域名下的脚本;
    • style-src 'self':仅允许加载同源的样式;
    • img-src 'self' data::仅允许加载同源的图片,以及 base64 格式的图片。

5. 职责与执行环境

防御环节 执行环境 漏洞职责 核心要求
输入验证 前端 + 后端 前端(辅助)+ 后端(核心) 后端必须进行输入验证,前端仅作为辅助,不能替代后端。
输出转义 前端 + 后端 反射 / 存储型(后端)+ DOM 型(前端) 后端负责输出到 HTML 页面的转义,前端负责 DOM 操作的转义。
内容安全策略(CSP) 服务端配置 + 浏览器执行 服务端 服务端负责配置合理的 CSP 头,浏览器负责执行 CSP 规则。

总结:Web 安全核心逻辑链

  1. 防御基础:同源策略隔离非同源资源,CORS 在安全前提下开放跨域权限;
  2. 主要攻击
    • XSS:注入脚本到目标站点,窃取 Cookie(前端 / 后端漏洞);
    • CSRF:利用 Cookie 自动携带特性,伪造用户操作(后端漏洞);
  3. 关键防御:Cookie 的HttpOnly(防 XSS)、SameSite(防 CSRF)、Secure(防窃听)配置,从载体层面阻断攻击。
  4. CSRF 防御:以 CSRF Token 为核心(服务端终极防御),配合 SameSite Cookie(浏览器端第一道防线),实现双重防御,彻底阻断身份伪造攻击;
  5. XSS 防御:以 输出过滤(输入验证 + 输出转义) 为核心(基础防御),配合 内容安全策略(CSP)(进阶补充防御),实现从 “源头过滤” 到 “执行阻断” 的全链路防御,彻底阻断脚本注入攻击;
  6. 职责划分
    • CSRF 防御的核心职责在后端
    • XSS 防御的核心职责:反射型 / 存储型在后端,DOM 型在前端

1. ELF文件结构

​ ELF文件的格式大致如下,其中比较重要的时文件头和段表:文件头描述文件的基本信息;段表类似所有段即section的指针表。

文件头定义了 ELF Magic Code、文件机器字节长度、数据存储方式、版本、运行平台、ABI 版本、ELF 重定位类型、硬件平台、硬件平台版本、入口地址、程序头入口与长度、Section Header 的偏移位置和长度以及 Section 数量等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 1000 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 64 (bytes)
Number of section headers: 15
Section header string table index: 14

段表:

​ 段表顾名思义,存储不同段的地方,实际存储的是段的描述符,该描述符会描述段的类型,大小等信息。可通过readelf -S main.o查看,因为下面需要用到一些段因此贴到这里。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
There are 15 section headers, starting at offset 0x3e8:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000000000000 00000040 000000000000003e 0000000000000000 AX 0 0 1
[ 2] .rela.text RELA 0000000000000000 00000310 0000000000000018 0000000000000018 I 12 1 8
[ 3] .data PROGBITS 0000000000000000 00000080 0000000000000005 0000000000000000 WA 0 0 4
[ 4] .bss NOBITS 0000000000000000 00000088 0000000000000005 0000000000000000 WA 0 0 4
[ 5] .rodata PROGBITS 0000000000000000 00000088 0000000000000007 0000000000000000 A 0 0 1
[ 6] .data.rel.local PROGBITS 0000000000000000 00000090 0000000000000008 0000000000000000 WA 0 0 8
[ 7] .rela.data.rel.lo RELA 0000000000000000 00000328 0000000000000018 0000000000000018 I 12 6 8
[ 8] .comment PROGBITS 0000000000000000 00000098 000000000000002a 0000000000000001 MS 0 0 1
[ 9] .note.GNU-stack PROGBITS 0000000000000000 000000c2 0000000000000000 0000000000000000 0 0 1
[10] .eh_frame PROGBITS 0000000000000000 000000c8 0000000000000058 0000000000000000 A 0 0 8
[11] .rela.eh_frame RELA 0000000000000000 00000340 0000000000000030 0000000000000018 I 12 10 8
[12] .symtab SYMTAB 0000000000000000 00000120 0000000000000198 0000000000000018 13 12 8
[13] .strtab STRTAB 0000000000000000 000002b8 0000000000000051 0000000000000000 0 0 1
[14] .shstrtab STRTAB 0000000000000000 00000370 0000000000000076 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
l (large), p (processor specific)
阅读全文 »

如何为一个 sh 脚本创建 mac 应用程序?

通过 “自动操作”(Automator)创建 Mac 应用程序,可按照以下步骤进行

  1. 打开自动操作应用:在 “应用程序” 文件夹中找到 “自动操作” 应用并打开。
  2. 选择文档类型:在新建文档窗口中,选择 “应用程序”,然后点击 “选择”。
  3. 添加操作步骤:在左侧的操作库中,浏览可用的操作。这些操作按类别分组,如文件处理、文本操作、互联网等。找到需要的操作后,双击该操作将其添加到右侧的工作区。可根据需求添加多个操作,并按逻辑顺序排列。
  4. 配置操作参数:针对添加到工作区的每个操作,设置具体的参数。例如,“获取指定的 Finder 项目” 操作,需选择具体的文件夹或文件;“播放声音” 操作,要选择播放的声音文件等。
  5. 测试工作流程:点击右上角的 “运行” 按钮,测试已设置好的工作流程,查看是否能按预期执行。如有问题,可及时调整操作或参数。
  6. 导出为应用程序:确认工作流程无误后,点击菜单栏中的 “文件”,选择 “导出”。在导出窗口中,将文件格式设置为 “应用程序”,为应用命名,并选择保存位置,如 “应用程序” 文件夹。
  7. 运行应用程序:保存后,可在启动台或保存位置找到创建好的应用程序图标,像普通应用一样点击运行。

mmap

在 Linux 中,”mmap” 通常指的是内存映射(Memory-Mapped)机制。mmap 是一个系统调用,它允许应用程序将文件或设备的内容映射到进程的地址空间。这样,文件或设备的内容就可以像访问普通内存一样进行读写操作,而无需使用传统的文件读写系统调用(如 read()write())。

mmap 机制的本质是提供一种高效的文件访问方式,通过以下几个方面实现:

  1. 直接内存访问
    通过将文件内容映射到进程的虚拟内存,应用程序可以直接通过内存地址访问文件数据,这避免了传统文件 I/O 调用中的数据复制步骤。

  2. 延迟加载
    mmap 创建的内存映射是按需加载的,这意味着文件的内容只有在实际访问时才会被加载到物理内存中。这可以提高对大文件的处理效率,并减少内存的使用。

  3. 共享内存
    mmap 可以用于创建共享内存区域,允许多个进程访问同一块内存。这是进程间通信(IPC)的一种方式,也可以用于共享文件的内容。

  4. 页缓存(Page Cache)
    使用 mmap 映射的文件数据会被操作系统的页缓存管理,这意味着频繁访问的数据可以保留在缓存中,从而加快访问速度。同时,对映射内存的修改可以延迟写回到文件,直到必要时才进行,这可以减少磁盘 I/O 操作。

  5. 虚拟内存管理
    mmap 依赖于操作系统的虚拟内存管理机制。当进程访问映射的内存区域时,如果对应的数据尚未加载到物理内存,操作系统会自动处理缺页中断(page fault),将数据从磁盘加载到内存中。

mmap 系统调用通常用于需要高效文件访问的场景,如数据库管理系统、文件编辑器、多媒体应用程序等。它也是实现内存映射文件和匿名映射(不与任何文件关联的内存区域)的基础。

总的来说,mmap 机制的本质是通过将文件或设备内容映射到虚拟内存,提供一种高效、灵活的内存访问和文件操作方式,同时充分利用操作系统的虚拟内存和页缓存功能。

阅读全文 »

软件工具

  1. 安装 sogou 输入法 https://shurufa.sogou.com/mac

  2. 安装 hombrew 包管理器 https://brew.sh/

  3. 安装 iterm2 工具 https://iterm2.com/

  4. 安装 oh-my-zsh 插件 https://ohmyz.sh/

    1. 安装 clashverge rev vpn 工具 https://www.clashverge.dev/
  5. 安装 git 命令行工具 brew install git https://git-scm.com/

  6. 安装 git-cz 插件 https://github.com/commitizen/cz-cli

    1
    2
    3
    npm install -g commitizen
    npm install -g cz-conventional-changelog
    echo '{ "path": "cz-conventional-changelog" }' > ~/.czrc
  7. 安装 node 环境 --global 全局安装 https://nodejs.org/en

  8. 安装 typora https://typora.io/

  9. 安装 hexo 工具 https://hexo.io/zh-cn/

  10. 安装 postman 网络请求工具 https://www.postman.com/

  11. 安装 alfred 效率工具 https://www.alfredapp.com/

  12. 安装 sublime 文本编辑器 https://www.sublimetext.com/

    1. 安装 submlime HTML-CSS-JS Prettify 插件,步骤: Tools->Command Palette->Package Control:Install Package
    2. 安装 submlime shellcheck 插件,步骤: Tools->Command Palette->Package Control:Install Package
  13. 安装 charles 抓包工具(破解https://www.charlesproxy.com/

  14. 安装 wireshark 网络抓包工具 https://www.wireshark.org/

  15. 安装 android studio开发工具 https://developer.android.com/studio

  16. 安装 vscode 开发工具 https://code.visualstudio.com/

  17. 安装 idea 开发工具 https://www.jetbrains.com/zh-cn/idea/

  18. 安装 Clion 开发工具 https://www.jetbrains.com.cn/clion/

  19. 安装 jdgui 反编译工具 https://java-decompiler.github.io/

  20. 安装 jadx 反编译工具 https://github.com/skylot/jadx, 通过自动操作.app 创建应用程序

  21. 安装 apktool 反编译以及重打包 工具 https://apktool.org/

  22. 安装 ghidra 反编译工具(c/c++反编译) https://github.com/NationalSecurityAgency/ghidra,通过自动操作.app 创建应用程序

  23. 安装 ida pro 反编译工具(破解版) https://www.123865.com/?notoken=1

  24. 安装 colc 代码统计工具 https://github.com/AlDanial/cloc?tab=readme-ov-file#install-via-package-manager

  25. 安装 mumu 模拟器 https://mumu.163.com/

  26. 安装 frida 动态hook 工具 https://frida.re/

环境配置

  1. 配置 ssh 环境

    1
    2
    3
    4
    ssh-keygen -t rsa -b 4096 -C "cxue.dev@qq.com"
    ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
    ssh-add ~/.ssh/xxx.pub
    ssh -T github.com ## 测试是否连通
  2. 配置 JAVA_HOME ANDROID_NDK_HOME环境变量

  3. 添加当前目录到 PATH 中,可以避免每次执行文件时添加 ./ 前缀: export PATH=${PATH}:.

  • 使用 sdk 工程调试另外一个 app 时需要修改 sdk工程中的 app 模块的包名和调试的 apk 一致。

  • 通过 dlopen() 的 so,默认不执行 jni_onload,只有 java层的 system.loadlibrary()才会执行。想要执行 jni_onload 执行 so 库初始化,需要手动调用 java 层的加载机制。

  • dlsym()函数获取符号地址时,要保证 so 的符号被导出。可以通过 nm -D xx.so 命令查看是否有对应的符号

  • Gcc 编译默认会命名修饰函数符号,所以需要对导出的符号进行 extern C 修饰。

  • nm xx.so 命令默认只会输出静态分析的符号,不会输出动态符号。输出动态符号需要 -D 选项。

  • DWARF 是一种标准的调试数据格式,用于在可执行文件中存储和描述程序的调试信息。

1
2
Android Debug Bridge version 1.0.41
Version 30.0.5-6877874

global options

1
2
3
4
5
6
7
8
-a         listen on all network interfaces, not just localhost
-d use USB device (error if multiple devices connected)
-e use TCP/IP device (error if multiple TCP/IP devices available)
-s SERIAL use device with given serial (overrides $ANDROID_SERIAL)
-t ID use device with given transport id
-H name of adb server host [default=localhost]
-P port of adb server [default=5037]
-L SOCKET listen on given socket for adb server [default=tcp:localhost:5037]

general commands

1
2
3
devices [-l]             list connected devices (-l for long output)
help show this help message
version show version num
阅读全文 »

gradle 参数传递默认为 string 类型

1
./gradlew -Pflag=false

参数为字符串类型时,这里判断为始终为真

1
2
3
4
5
6
7
8
9
10
//错误
if (flag) {
//todo
}


//正确
if (Boolean.valueOf(flag)) {
//todo
}

MySQL中的SQL语句执行顺序,通常指的是查询(SELECT)语句的各个组成部分的逻辑执行顺序。虽然我们按照一定的语法顺序编写SQL语句,但是数据库系统在查询优化和执行过程中,并不是按照我们编写的顺序执行的。

以下是一个典型的SELECT语句的编写顺序:

1
2
3
4
5
6
7
1 SELECT
2 FROM
3 WHERE
4 GROUP BY
5 HAVING
6 ORDER BY
7 LIMIT

然而,MySQL实际执行这些操作的顺序大致如下:

  1. FROM:确定要从哪个表(或者多个表的连接)中检索数据。
  2. ON:应用JOIN条件,用于多个表的情况。
  3. JOIN:如果有多个表需要连接,会在这个阶段进行。
  4. WHERE:根据指定的条件对数据进行过滤。
  5. GROUP BY:将数据分组,通常用于聚合函数(如COUNT, SUM, AVG等)。
  6. HAVING:对分组后的结果进行过滤,通常与GROUP BY联合使用。
  7. SELECT:选取表中的特定列,如果有表达式或者聚合函数,也会在这一步计算。
  8. DISTINCT:去除重复的行,保证查询结果的唯一性。
  9. ORDER BY:对查询结果进行排序,这一步通常在所有的行被选取之后进行。
  10. LIMIT:限制查询结果的数量,通常用于分页。

img

需要注意的是,执行顺序并不是绝对固定的,数据库优化器可能会根据各种因素(如索引的存在,表的大小等)对执行计划进行调整,以提高查询的效率。因此,上述顺序应当被视为一种逻辑执行顺序,而不是实际的物理执行顺序。

0%