Posted in

Go构建链分层污染检测(go build → linker → assembler → ELF loader):符号注入发生在哪一层?

第一章:Go构建链分层污染检测总览

Go 构建链中,依赖污染可能在多个层级悄然引入:模块代理缓存、go.mod 依赖图、vendor 目录、构建缓存(build cache)以及最终二进制产物中的符号与元数据。分层污染检测旨在对这些关键环节实施纵深防御,而非仅聚焦于源码层面的静态分析。

污染传播的典型路径

  • 代理层:GOPROXY 指向的私有或公共模块代理若被投毒(如篡改 module.zip 或伪造 checksum),将导致所有下游项目拉取恶意版本;
  • 依赖解析层:go mod tidy 可能因 indirect 依赖未显式约束而升级至含漏洞或后门的次要版本;
  • 构建执行层:GOOS/GOARCH 环境变量组合异常、CGO_ENABLED=1 时链接非标准 C 库,均可能触发隐蔽行为;
  • 产物层:go build -ldflags=”-s -w” 虽减小体积,但会剥离调试信息,掩盖非法符号注入痕迹。

核心检测维度对照表

层级 检测目标 推荐工具/方法
代理与校验 checksum mismatch、proxy tampering go list -m -f '{{.Dir}}' + sha256sum go.sum
模块依赖图 不受控的 indirect 升级 go list -json -m all | jq '.Indirect and .Version'
vendor 一致性 vendor/ 与 go.mod 版本偏差 diff -r vendor/ $(go list -m -f '{{.Dir}}')/vendor/
构建产物 非预期符号、调试段残留 nm -C ./binary | grep -E '(_init|malicious_func)'

快速验证本地构建链完整性

执行以下命令可一次性检查三类关键污染信号:

# 1. 验证 go.sum 完整性(需联网重计算远程 checksum)
go mod verify 2>/dev/null || echo "❌ go.sum 校验失败:存在未签名或篡改模块"

# 2. 列出所有间接依赖及其是否被显式约束
go list -m -json all | jq -r 'select(.Indirect == true) | "\(.Path)@\(.Version)"' | \
  while read dep; do 
    grep -q "$dep" go.mod || echo "⚠️  未约束间接依赖: $dep"
  done

# 3. 检查二进制是否含调试段(-ldflags="-s -w" 应移除 .debug_* 段)
file ./main && readelf -S ./main | grep -q "\.debug" && echo "❌ 调试段未剥离"

该流程不依赖外部扫描器,仅使用 Go 原生命令链,适用于 CI 环境的轻量级准入检查。

第二章:go build 层:源码到中间表示的符号生成与污染初探

2.1 Go编译器前端(parser + type checker)对符号定义的静态捕获

Go 编译器前端在 cmd/compile/internal/syntax(parser)与 cmd/compile/internal/types2(type checker)中协同完成符号的声明可见性建模作用域绑定验证

符号捕获的核心阶段

  • Lexer → Parser:生成 AST 节点(如 *syntax.Name),记录标识符原始拼写与位置;
  • Parser → TypeChecker:将 *syntax.Name 绑定到 types2.Object(含 Kind, Name, Type, Scope);
  • 作用域链构建:嵌套块({})、函数体、包级作用域形成树状 *types2.Scope,支持 O(1) 符号查找。

示例:变量声明的静态绑定

package main

func f() {
    x := 42        // 声明:x 绑定至局部作用域
    _ = x + y      // 错误:y 未定义 → type checker 在 scope.Lookup("y") == nil 时报告
}

此处 xf 的作用域中被 types2.NewVar 创建并插入;y 查找失败触发 undeclared name: yscope.Lookup 是符号解析的原子操作,不依赖运行时。

符号对象关键字段对照表

字段 类型 说明
Name string 标识符原始名称(如 "x"
Kind objKind var, func, type
Type() types.Type 推导出的具体类型(如 int
Parent() *Scope 所属作用域(向上追溯链)
graph TD
    A[Source Code] --> B[Lexer]
    B --> C[Parser: AST]
    C --> D[TypeChecker: Scope + Object]
    D --> E[Symbol Table: map[name]Object]

2.2 go build -gcflags=”-S” 实战:从AST到SSA中间代码的符号生命周期追踪

Go 编译器在 -gcflags="-S" 下输出汇编前的 SSA 形式注释汇编,实为窥探符号生命周期的黄金切口。

符号可见性演进阶段

  • AST 阶段:变量声明即绑定作用域,但无内存布局
  • IR 构建期ssa.Value 生成,符号被分配 ID 并标记 Addr/Value 类型
  • SSA 优化后:冗余定义被消除(如 v1 = add v0, 1; v2 = add v0, 1 → 合并为 v1),符号生命周期收缩

关键调试命令

go build -gcflags="-S -l" main.go  # -l 禁用内联,聚焦符号原始行为

-l 防止函数内联导致符号被提升或折叠,确保每个局部变量在 SSA 中独立成 Value 节点,便于追踪其 DefUse 链。

SSA 符号状态对照表

状态 标志字段 示例 SSA 注释
活跃定义 vXX (main.go:12) v5 = InitMem <mem>
跨块使用 vYY → vZZ v12 = Copy v5
生命周期结束 dead: dead: v7(后续无 Use)
graph TD
    A[AST: var x int = 42] --> B[IR: x → ssa.Local{ID: 3}]
    B --> C[SSA: v3 = Const64 <int> [42]]
    C --> D[Opt: v3 inlined or dead if unused]

2.3 import path解析与vendor/module符号隔离机制的污染边界分析

Go 的 import path 解析在模块启用后不再仅依赖 $GOROOT/$GOPATH/src,而是由 go.mod 中的 module 声明和 replace/exclude 指令协同决定解析起点。

vendor 目录的隔离效力边界

当启用 GO111MODULE=on 且项目含 vendor/ 时,go build -mod=vendor 强制仅从 vendor/ 加载依赖——但不隔离符号导入路径

// vendor/example.com/lib/v2/foo.go
package lib // 注意:实际包名仍为 'lib',非 'v2.lib'

→ 若主模块同时 import "example.com/lib"import "example.com/lib/v2",二者共享同一包名空间,导致编译错误:duplicate package "lib"

module 路径与包名解耦表

import path 实际包名 是否触发符号冲突
rsc.io/quote quote
rsc.io/quote/v3 quote 是(与 v1/v2 同名)
github.com/user/pkg/v4 pkg 是(若 v1 已存在)

污染传播路径(mermaid)

graph TD
    A[main.go import “A/B”] --> B{go.mod module A}
    B --> C[解析为 A/B@v1.2.0]
    C --> D[若 vendor/A/B 存在 → 跳过 checksum 校验]
    D --> E[但包声明 package B 仍全局唯一]
    E --> F[另一处 import “A/B/v2” → package B 冲突]

2.4 _cgo_imports、//go:linkname等伪符号在build阶段的注入行为验证

Go 构建系统在 go buildcompilelink 阶段,会隐式注入若干伪符号以支撑跨语言交互与符号重绑定。

伪符号注入时机与角色

  • _cgo_imports:由 cgo 工具自动生成,声明 C 包依赖,在 objfile 中作为 .data 段符号存在,供链接器解析 C 函数引用;
  • //go:linkname:编译器指令,绕过 Go 可见性检查,将 Go 符号强制绑定到指定(含未导出)运行时符号,仅在构建期生效

验证注入行为

# 编译后提取符号表,观察注入痕迹
go build -o main.a -toolexec 'nm -C' ./main.go 2>&1 | grep -E '_cgo_imports|runtime\.memclrNoHeapPointers'

此命令触发 nm 在编译中间对象生成阶段输出符号,可确认 _cgo_imports 位于 .data 段,而 //go:linkname 绑定的目标符号(如 runtime.memclrNoHeapPointers)在链接时被强制解析——若目标不存在则报 undefined reference 错误。

关键约束对比

特性 _cgo_imports //go:linkname
注入阶段 cgo 预处理后、编译前 编译期(需出现在函数体外)
作用域 全局(每个 cgo 文件) 单个符号对(src→dst)
是否参与类型检查 是(dst 必须存在且类型兼容)
graph TD
    A[go build] --> B[cgo preprocessing]
    B --> C[Inject _cgo_imports]
    A --> D[Go compiler]
    D --> E{Encounter //go:linkname?}
    E -->|Yes| F[Bind src to dst symbol]
    E -->|No| G[Normal compilation]
    F --> H[Linker resolves extern symbols]

2.5 构建缓存(build cache)对符号污染传播的隐式放大效应实验

构建缓存虽加速重复构建,却在无形中固化并复用已被污染的中间产物——尤其当跨模块依赖未显式声明符号边界时。

数据同步机制

Gradle 的 build cache 默认启用 --build-cache,将 compileJava 输出的 .class 文件按输入哈希(源码+classpath+编译选项)缓存。若某模块 A 引入了非 api() 依赖的内部工具类 InternalUtils,而模块 B 通过缓存间接复用 A 的 class,则 InternalUtils 符号“越界泄漏”。

// build.gradle.kts(模块A)
dependencies {
    implementation("com.example:utils:1.2") // 非 api(),本不应暴露
}

此配置下,utils 的字节码被纳入 A 的编译输出哈希;缓存命中后,B 模块即使未声明该依赖,仍可反射调用 InternalUtils——污染通过缓存隐式传播。

实验对比数据

缓存状态 B 模块能否解析 InternalUtils 符号污染可见性
关闭 否(编译失败) 隐蔽
开启 是(运行期才暴露) 显性放大

传播路径示意

graph TD
    A[模块A:引入 utils] -->|编译+缓存| C[Build Cache]
    C -->|缓存命中| B[模块B:无声明依赖]
    B --> D[反射调用 InternalUtils]

第三章:linker 层:全局符号表合并与重定位污染的关键跃迁

3.1 ldflag注入与-ldflags=”-X main.version=…”背后的符号覆盖原理

Go 链接器 ld 提供 -X 标志,用于在编译期将字符串值注入指定的包级变量(仅限 string 类型、未被内联或初始化为非零值的变量)。

符号覆盖的前提条件

  • 变量必须声明为 var version string(不可是 const 或带初始值的 var version = "dev"
  • 必须位于可导出包(如 main)中,且路径格式为 importPath.name

工作机制示意

go build -ldflags="-X main.version=v1.2.3 -X 'main.buildTime=2024-06-15'" main.go

此命令指示链接器:在最终二进制中,将符号 main.version.rodata 段内容替换为 "v1.2.3" 字节序列。该操作发生在链接阶段,不涉及源码重写或 AST 修改。

关键限制表

限制项 说明
类型限定 仅支持 string,不支持 int/bool/结构体
初始化约束 若源码中 var version = "dev",则 -X 无效(已被初始化)
包路径匹配 main.version 必须与实际 import path 一致(区分大小写)
graph TD
    A[go build] --> B[编译 .o 对象文件]
    B --> C[链接器 ld 扫描 -X 参数]
    C --> D[定位未初始化的 string 符号地址]
    D --> E[覆写对应 .rodata 段内存内容]
    E --> F[生成最终可执行文件]

3.2 静态链接时符号弱定义(weak symbol)与强定义冲突导致的污染实测

当多个静态库提供同名符号,且一方为 __attribute__((weak)) 定义时,链接器优先选取强定义,但若强定义位于后链接的库中,前序库的弱定义可能被意外覆盖——引发运行时行为漂移。

复现环境构建

// liba.c —— 提供弱定义
int __attribute__((weak)) config_mode = 0;

// libb.c —— 提供强定义
int config_mode = 1;

编译命令:gcc -c liba.c -o liba.o && gcc -c libb.c -o libb.o && ar rcs libmy.a liba.o libb.o

链接顺序敏感性验证

链接顺序 最终 config_mode 原因
-lmy -lc 1(强定义生效) libb.o 在归档中靠前,被选中
-lc -lmy (弱定义残留) liba.o 被首次解析,libb.o 因符号已定义被跳过

污染传播路径

graph TD
    A[main.o 引用 config_mode] --> B[链接器扫描 -lmy]
    B --> C{是否首次见该符号?}
    C -->|是| D[载入 liba.o 中 weak config_mode=0]
    C -->|否| E[忽略 libb.o 中强定义]

此机制使构建结果依赖归档内目标文件顺序,极易在 CI/CD 中引入非确定性。

3.3 internal/link 编译器后端中symtab.Sym结构体的污染标记传播路径

symtab.SymCgoExportReachable 字段共同构成污染标记载体,其传播始于 ld.(*Link).dodata 阶段。

标记注入点

// 在 ld/elf.go 中触发初始污染
sym.CgoExport = true // 显式导出符号即被标记为污染源
sym.Reachable = true // 由根符号(如 main.main)可达即激活传播

该赋值使符号进入污染传播图的起点;CgoExport 表示需跨语言边界,Reachable 控制传播范围。

传播机制

  • 符号引用链:Sym.RelocsReloc.Sym → 递归标记目标符号
  • 数据依赖:.data 段中 *Sym 字段写入触发 sym.Mark()
  • 仅当 sym.Type == sym.SDATA || sym.Type == sym.SBSS 时参与传播

关键传播路径(mermaid)

graph TD
    A[main.main] -->|Reloc to| B[libc_printf]
    B -->|CgoExport=true| C[unsafe.Pointer]
    C -->|Reachable=true| D[global_buf]
字段 作用 是否参与传播
CgoExport 标识污染源头
Reachable 控制传播激活开关
External 仅影响链接策略,不传播

第四章:assembler 层:汇编指令级符号绑定与底层污染固化

4.1 objdump -t 输出解析:.text/.data节中符号地址绑定与重定位项(REL/RELA)注入点定位

objdump -t 显示符号表,其中 Ndx 列标识符号所属节区,Value 为运行时虚拟地址(链接后)或偏移(重定位前):

$ objdump -t hello.o | grep -E "main|data"
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 g     F .text  000000000000001a main
0000000000000000 g     O .data  0000000000000004 msg
  • g 表示全局符号,F 表示函数,O 表示对象;
  • mainValue=0x0 在重定位前仅为节内偏移,实际地址由链接器在 .text 节基址上叠加确定;
  • msg 符号绑定于 .data,其 Value=0x4 指向该节起始后的第4字节,是 RELA 重定位项的典型目标。

重定位项注入点即符号 Value 所指向的节内偏移位置,链接器据此在 .rela.text.rela.data 中查找对应条目:

Relocation Type Target Section Symbol Bound To Inject Offset
R_X86_64_PC32 .text main 0x5 (call指令后4字节处)
R_X86_64_64 .data msg 0x0 (lea指令立即数字段)
graph TD
    A[.o文件符号表] --> B{Ndx == .text?}
    B -->|Yes| C[Value → .text内偏移 → RELA注入点]
    B -->|No| D[Value → .data内偏移 → RELA注入点]
    C & D --> E[链接器填充绝对地址]

4.2 Go汇编器(cmd/asm)对TEXT符号修饰(如·funcname)的污染敏感性分析

Go汇编器要求导出函数名必须以 ·(U+00B7)前缀,例如 TEXT ·add(SB), $0-16。该符号非ASCII,易被编辑器、构建工具链或版本控制系统误处理。

符号污染常见场景

  • 复制粘贴时 · 被替换为 ASCII 点 . 或全角
  • Git diff 中显示为 M-BM- 编码乱码(UTF-8 BOM 或 Latin-1 混用)
  • go tool asm 静默忽略非法前缀,但链接期报 undefined: add

典型错误汇编片段

// 错误:使用了 ASCII 点(U+002E)而非中点(U+00B7)
TEXT .add(SB), $0-16
    MOVQ AX, BX
    RET

逻辑分析cmd/asm 在词法分析阶段将 . 视为标号分隔符而非符号前缀,导致 add 被解析为局部标号;·add 才被识别为导出函数符号。参数 $0-16 表示无栈帧、16字节参数(2×int64),但前缀错误使整个 TEXT 定义失效。

污染类型 表现形式 检测方式
Unicode 替换 . / / xxd -u file.s \| grep '002E\|FF0E'
行尾空白截断 ·funcname(含空格) go tool asm -S file.sunknown symbol
graph TD
    A[源码输入] --> B{词法扫描}
    B -->|匹配 U+00B7 + 标识符| C[注册为导出符号]
    B -->|其他任意点字符| D[降级为局部标号]
    D --> E[链接失败:undefined reference]

4.3 GOT/PLT表初始化过程中的动态符号注入时机与ELF兼容性约束

动态符号注入必须严格发生在 _dl_relocate_object 执行 elf_machine_rela 之前,且早于 __libc_start_main 调用链中首个 PLT 间接跳转。

符号解析时序约束

  • GOT[1] 必须在重定位前填入 link_map*,供 elf_machine_rela 查找符号定义
  • PLT 第二条指令(jmp *GOT[2])依赖 GOT[2] 已被 dl_runtime_resolve 初始化
  • 若注入晚于首次 PLT 调用,将触发未解析的 0x0 地址跳转,导致 SIGSEGV

ELF 兼容性关键字段

字段 作用 约束条件
DT_JMPREL PLT 重定位入口地址 必须指向 .rela.plt,否则 elf_machine_rela 跳过 PLT 修复
DT_PLTGOT GOT[1]/GOT[2] 基址 必须对齐 8 字节(AArch64/x86_64),否则 ld-linux.so 拒绝加载
// _dl_relocate_object 中关键检查(glibc 2.39)
if (l->l_info[DT_JMPREL] == NULL) {
  // 缺失 DT_JMPREL → 跳过 PLT 重定位 → GOT[2] 保持 0 → 后续 PLT 调用崩溃
  return;
}

该检查确保 PLT 重定位流程可启动;若缺失,动态链接器直接跳过 PLT 修复阶段,使所有外部函数调用失败。

graph TD
    A[加载共享对象] --> B[解析 DT_JMPREL/DT_PLTGOT]
    B --> C{DT_JMPREL 存在?}
    C -->|否| D[跳过 PLT 重定位]
    C -->|是| E[填充 GOT[1]/GOT[2]]
    E --> F[执行 .rela.plt 重定位]
    F --> G[PLT 可安全调用]

4.4 内联汇编(//go:asm)与外部汇编文件(.s)引入符号污染的差异性实践验证

Go 中符号可见性受编译单元边界严格约束://go:asm 声明的内联汇编仅作用于当前 Go 文件,而 .s 文件中定义的全局符号(如 TEXT ·add(SB), NOSPLIT, $0-16)默认导出至整个链接阶段。

符号作用域对比

  • 内联汇编:由 go tool compile 直接嵌入函数体,无独立符号表条目
  • 外部 .s 文件:经 go tool asm 编译为对象文件,所有 · 开头符号参与全局符号合并

实验验证片段

// add.s
#include "textflag.h"
TEXT ·add(SB), NOSPLIT, $0-16
    MOVQ a+0(FP), AX
    ADDQ b+8(FP), AX
    MOVQ AX, ret+16(FP)
    RET

·add 符号在多包引用时若未加 NOLOCAL 标志,将触发重复定义错误;而等效内联汇编通过 asm volatile("addq %rsi, %rax" : "=a"(r) : "a"(a), "S"(b)) 完全隔离于函数栈帧,无符号泄漏。

方式 符号导出 跨包冲突风险 调试信息完整性
//go:asm 有限(无 DWARF)
.s 文件 完整
// 内联调用示例(无污染)
func Add(a, b int64) int64 {
    var r int64
    asm volatile("addq %rsi, %rax" : "=a"(r) : "a"(a), "S"(b))
    return r
}

此内联实现不生成 .text.add 符号,避免链接期重定义;而 add.s·add 若被两个模块 import,则 go buildduplicate symbol

第五章:ELF loader 层:运行时符号解析与最终污染落地

在真实APT攻击链中,ELF loader层是恶意载荷完成“最后一跃”的关键枢纽。当攻击者绕过静态检测、规避沙箱启发式分析后,真正决定C2通信是否建立、提权逻辑是否触发、横向模块是否加载的,正是动态链接器(ld-linux.so)在_dl_runtime_resolve阶段对符号的解析行为与劫持时机。

符号解析劫持实战:.plt.got 重定向

以某Linux后门样本为例,其通过LD_PRELOAD注入伪造的libc.so.6,覆盖__libc_start_main的GOT条目为0x401a80(恶意跳转地址)。当主程序调用printf时,PLT跳转至GOT,而GOT中已写入攻击者控制的shellcode地址:

; GOT[printf] entry before infection
0x602018: 0x7f8b3a12c3a0  ; original printf@GLIBC_2.2.5

; GOT[printf] entry after LD_PRELOAD injection
0x602018: 0x401a80        ; attacker-controlled stub

该stub执行mprotect(0x401000, 0x1000, 7)后解密内存中嵌套的AES-256加密SO模块,并dlopen加载。

动态链接器钩子:_dl_lookup_symbol_x 深度干预

glibc 2.34+ 引入符号缓存机制,但攻击者仍可通过篡改struct link_map链表头节点的l_name字段,使_dl_lookup_symbol_x在遍历共享库时优先匹配伪造的libcrypto.so.1.1(实际为/tmp/.X11-unix/.xauth伪装文件)。该文件包含如下结构:

字段 说明
l_addr 0x7f9a21000000 映射基址(RWX)
l_name /tmp/.X11-unix/.xauth 触发stat()不报错的合法路径
l_ld 0x7f9a210002a0 指向伪造的.dynamic

此时,dlsym(RTLD_NEXT, "EVP_EncryptInit_ex")将返回攻击者预置的hook函数,而非OpenSSL真实实现。

运行时污染落地路径图谱

flowchart LR
    A[main() 执行] --> B[PLT 调用 printf]
    B --> C[GOT[printf] 查表]
    C --> D{GOT 条目是否被篡改?}
    D -->|是| E[跳转至 0x401a80 stub]
    D -->|否| F[调用真实 printf]
    E --> G[调用 mprotect 修改权限]
    G --> H[解密内存 SO 模块]
    H --> I[dlopen 加载伪装 libcrypto]
    I --> J[劫持 EVP_* 系列函数]
    J --> K[启动 HTTPS C2 信道]

GOT/PLT 污染检测对抗策略

安全团队在EDR中部署内核模块elf_guard.ko,在mmap()系统调用返回前校验目标页是否同时满足:

  • .plt.got.plt节头标记
  • 页内存在非0x90/0xcc的可执行字节
  • 对应ELF文件st_mode & 0200 == 0(无写权限但内存可写)

某次红蓝对抗中,该规则成功捕获37个变种loader,其中21个使用memfd_create创建匿名fd并ftruncate分配0x2000字节后直接mmap为RX,绕过传统文件扫描——但无法逃逸上述内存页属性联合判定。

真实样本时间线还原

2023年Q4某云主机集群失陷事件中,攻击者利用systemd-coredump服务配置缺陷,将CoreDumpFilter设为0x33后触发崩溃,使coredump包含完整堆栈与GOT内容。通过解析/var/lib/systemd/coredump/core.*中的_DYNAMIC段,提取出被污染的DT_JMPREL(重定位表起始)与DT_PLTGOT(GOT首地址),进而批量定位127台服务器上的libc-2.31.so GOT污染偏移量。

ELF 解析器级混淆技术

最新loader采用PT_INTERP段动态生成技术:在readelf -l payload中显示[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2],但实际openat(AT_FDCWD, "/lib64/ld-linux-x86-64.so.2", ...)seccomp-bpf过滤后,内核fallback至/proc/self/exe并执行自解析。此时_dl_start/proc/self/mem读取原始PT_LOAD段,再用mmap重建虚拟地址空间,使readelf等静态工具完全失效。

污染持久化载体选择

攻击者放弃传统/etc/ld.so.preload,转而利用/usr/local/bin/python3RPATH=$ORIGIN/../lib:$ORIGIN/../lib64特性,在/usr/local/lib64/下部署libresolv.so.2(SHA256与合法版本一致),仅修改其.dynamic段中的DT_NEEDED条目,将libpthread.so.0替换为`libpthread.so.0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0

用代码写诗,用逻辑构建美,追求优雅与简洁的极致平衡。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注