Projects STRLCPY redress Commits 289731d2
🤬
  • ■ ■ ■ ■ ■ ■
    .github/workflows/go.yml
     1 +name: Main
     2 + 
     3 +on:
     4 + push:
     5 + branches:
     6 + - master
     7 + - develop
     8 + tags:
     9 + - '*'
     10 + 
     11 +jobs:
     12 + CI:
     13 + runs-on: ubuntu-latest
     14 + steps:
     15 + - uses: actions/checkout@v2
     16 + with:
     17 + submodules: true
     18 + 
     19 + - name: Set up Go
     20 + uses: actions/setup-go@v2
     21 + with:
     22 + go-version: 1.16
     23 + 
     24 + - name: Build
     25 + run: make release
     26 + 
     27 + - name: Upload files to a GitHub release
     28 + if: startsWith(github.ref, 'refs/tags/')
     29 + env:
     30 + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
     31 + run: gh release create -d ${{ github.ref }} ./dist/*
     32 +
     33 + 
  • ■ ■ ■ ■ ■ ■
    .github/workflows/release.yml
     1 +name: Build release
     2 + 
     3 +on:
     4 + workflow_dispatch:
     5 + inputs:
     6 + ver:
     7 + description: 'Tag version for the release'
     8 + required: true
     9 + 
     10 +jobs:
     11 + manual_release:
     12 + runs-on: ubuntu-latest
     13 + steps:
     14 + - uses: actions/checkout@v2
     15 + with:
     16 + ref: ${{ github.event.inputs.ver }}
     17 + submodules: true
     18 + 
     19 + - name: Set up Go
     20 + uses: actions/setup-go@v2
     21 + with:
     22 + go-version: 1.16
     23 + 
     24 + - name: Build
     25 + run: make release
     26 + 
     27 + - name: Upload files to a GitHub release
     28 + env:
     29 + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
     30 + run: gh release create -d ${{ github.event.inputs.ver }} ./dist/*
     31 +
     32 + 
  • ■ ■ ■ ■ ■ ■
    .gitmodules
     1 +[submodule "gore"]
     2 + path = gore
     3 + url = [email protected]:goretk/gore.git
     4 + 
  • ■ ■ ■ ■ ■ ■
    .travis.yml
    1  -language: go
    2  - 
    3  -go:
    4  - - "1.16.x"
    5  - 
    6  -env:
    7  - - GO111MODULE=on
    8  - 
    9  -os:
    10  - - linux
    11  - 
    12  -script:
    13  - - make release
    14  - 
    15  -deploy:
    16  - provider: releases
    17  - skip_cleanup: true
    18  - draft: true
    19  - on:
    20  - tags: true
    21  - api_key: $GITHUB_TOKEN
    22  - file_glob: true
    23  - file:
    24  - - ./dist/*.zip
    25  - - ./dist/*.tar.gz
    26  - 
  • ■ ■ ■ ■ ■ ■
    Makefile
    skipped 6 lines
    7 7  SHELL = /bin/bash
    8 8  DIR = $(shell pwd)
    9 9  GO = go
     10 + 
    10 11  VERSION=$(shell git describe --tags 2> /dev/null || git rev-list -1 HEAD)
     12 +GOREVER=$(shell grep "goretk\/gore v" go.mod | awk '{print $$2;}')
     13 +GOVER=$(shell go version | awk '{print $$3;}')
     14 +LDEXTRA=-X "main.redressVersion=$(VERSION)" -X "main.goreVersion=$(GOREVER)" -X "main.compilerVersion=$(GOVER)"
    11 15   
    12 16  NO_COLOR=\033[0m
    13 17  OK_COLOR=\033[32;01m
    skipped 6 lines
    20 24  PACKAGE=$(APP)-$(VERSION)
    21 25  TAR_ARGS=cfz
    22 26  RELEASE_FILES=LICENSE README.md
    23  -BUILD_OPTS=-ldflags="-s -w -X main.redressVersion=$(VERSION)" -trimpath
     27 +BUILD_OPTS=-ldflags='-s -w $(LDEXTRA)' -trimpath
    24 28   
    25 29  # Linux options
    26 30   
    skipped 31 lines
    58 62  .PHONY: linux
    59 63  linux: ## Make binary for Linux
    60 64   @echo -e "$(OK_COLOR)[$(APP)] Build for Linux$(NO_COLOR)"
    61  - @$(LINUX_GO_ENV) $(GO) build -o $(APP)$(BUILD_OPTS) .
     65 + @$(LINUX_GO_ENV) $(GO) build -o $(APP) $(BUILD_OPTS) .
    62 66   
    63 67  .PHONY: macos
    64 68  macos: ## Make binary for macOS
    65 69   @echo -e "$(OK_COLOR)[$(APP)] Build for macOS$(NO_COLOR)"
    66  - @$(MACOS_GO_ENV) $(GO) build -o $(APP)$(BUILD_OPTS) .
     70 + @$(MACOS_GO_ENV) $(GO) build -o $(APP) $(BUILD_OPTS) .
    67 71   
    68 72  .PHONY: build
    69 73  build: ## Make binary
    skipped 43 lines
  • ■ ■ ■ ■ ■ ■
    README.md
    skipped 11 lines
    12 12  behaves accordingly.
    13 13   
    14 14  For the examples shown the malware __pplauncher__
    15  -(`f94ca9b1b01a7b06f19afaac3fbe0a43075c775a`) will be used. A sample of the
    16  -binary can be downloaded [here](https://keybase.pub/joakimkennedy/gomalware/).
     15 +(`f94ca9b1b01a7b06f19afaac3fbe0a43075c775a`) will be used.
    17 16  The malware was first reported by
    18 17  [Malwarebytes](https://blog.malwarebytes.com/threat-analysis/mac-threat-analysis/2018/05/new-mac-cryptominer-uses-xmrig/).
    19 18   
    skipped 5 lines
    25 24  is to print more information than what is asked by the user.
    26 25   
    27 26  ```
    28  -$ redress -h
    29  -Usage of redress:
    30  - -compiler
    31  - Print information
    32  - -filepath
    33  - Include file path for packages
    34  - -interface
    35  - Print interfaces
    36  - -method
    37  - Print type's methods
    38  - -pkg
    39  - List packages
    40  - -src
    41  - Print source tree
    42  - -std
    43  - Include standard library packages
    44  - -struct
    45  - Print structs
    46  - -type
    47  - Print all type information
    48  - -unknown
    49  - Include unknown packages
    50  - -vendor
    51  - Include vendor package
    52  - -version
    53  - Print redress version
     27 +% redress -h
     28 +______ _
     29 +| ___ \ | |
     30 +| |_/ /___ __| |_ __ ___ ___ ___
     31 +| // _ \/ _ | '__/ _ / __/ __|
     32 +| |\ | __| (_| | | | __\__ \__ \
     33 +\_| \_\___|\__,_|_| \___|___|___/
     34 + 
     35 +Usage:
     36 + redress [command]
     37 + 
     38 +Available Commands:
     39 + completion generate the autocompletion script for the specified shell
     40 + help Help about any command
     41 + info Print summary information.
     42 + packages List packages.
     43 + r2 Use redress with in r2.
     44 + source Source Code Projection.
     45 + types List types.
     46 + version Display redress version information.
     47 + 
     48 +Flags:
     49 + -h, --help help for redress
     50 + 
     51 +Use "redress [command] --help" for more information about a command.
     52 +```
     53 + 
     54 +### Information
     55 + 
     56 +Information about Go binary is shown by using the `info` command. Information
     57 +displayed include the compiler version and the date it was released, the build
     58 +id, GoRoot, and the folder path for the main package.
     59 +```
     60 +% redress info pplauncher
     61 +OS macOS
     62 +Arch amd64
     63 +Compiler 1.10 (2018-02-16)
     64 +Build ID 3xkvDz8awVOl0TA6jJs9/tcgWkdP85A-MJ6hpnmKm/_xkzRloiGp8H5mHsQgkh/7Kj4aF9BTT0MY_gaQnQI
     65 +GoRoot /usr/local/Cellar/go/1.10/libexec
     66 +Main root /Users/ronald/git/go-workspace/src/keybase.io/safetycrew/pplauncher
     67 +# main 1
     68 +# std 35
     69 +# vendor 2
    54 70  ```
    55 71   
    56 72  ### Packages
    57 73   
    58  -The different Go packages used in the binary can be extracted with the `-pkg`
    59  -flag. *Redress* tries to only print the packages that are part of the project
     74 +The different Go packages used in the binary can be extracted with the `packages`
     75 +command. *Redress* tries to only print the packages that are part of the project
    60 76  and skips standard library and 3rd party library packages.
    61 77   
    62 78  ```
    63  -$ redress -pkg pplauncher
     79 +% redress packages pplauncher
    64 80  Packages:
     81 +Name Version
     82 +---- -------
    65 83  main
    66 84  ```
    67 85   
    68 86  Sometimes though, *redress* fails to classify a package. In this case, the
    69  -unclassified packages can be printed by also provide the `-unknown` flag:
     87 +unclassified packages can be printed by also provide the `--unknown` flag:
    70 88   
    71 89  ```
    72  -$ redress -pkg -unknown pplauncher
     90 +% redress packages pplauncher --unknown
    73 91  Packages:
     92 +Name Version
     93 +---- -------
    74 94  main
    75 95   
    76  -Unknown Libraries:
    77  - 
     96 +Unknown Packages:
     97 +Name Version
     98 +---- -------
    78 99  ```
    79  -To also include the standard library, use the `-std` flag. For 3rd party
    80  -packages, use the flag `-vendor`.
     100 +To also include the standard library, use the `--std` flag. For 3rd party
     101 +packages, use the flag `--vendor`.
    81 102   
    82 103  ```
    83  -$ redress -pkg -vendor -std pplauncher
     104 +% redress packages pplauncher --std --vendor
    84 105  Packages:
     106 +Name Version
     107 +---- -------
    85 108  main
    86 109   
    87 110  Vendors:
     111 +Name Version
     112 +---- -------
    88 113  vendor/golang_org/x/net/route
    89 114  vendor/golang_org/x/net/route.(*wireFormat).(vendor/golang_org/x/net/route
    90 115   
    91  -Standard Libraries:
     116 +Standard Library Packages:
     117 +Name Version
     118 +---- -------
    92 119  bufio
    93 120  bytes
    94 121  compress/flate
    skipped 2 lines
    97 124  encoding/binary
    98 125  errors
    99 126  fmt
    100  -go
    101 127  hash
    102 128  hash/crc32
    103 129  internal/cpu
    skipped 23 lines
    127 153  unicode/utf8
    128 154  ```
    129 155   
    130  -The folder location for the package can also be included by using the
    131  -`-filepath` flag.
     156 +The folder locations can be included in the output by using the `--filepath` flag.
    132 157   
    133 158  ```
    134  -$ redress -pkg -std -filepath pplauncher
     159 +% redress packages pplauncher --std --filepath
    135 160  Packages:
    136  -main | /Users/ronald/git/go-workspace/src/keybase.io/safetycrew/pplauncher
    137  - 
    138  -Standard Libraries:
    139  -bufio | /usr/local/Cellar/go/1.10/libexec/src/bufio
    140  -bytes | /usr/local/Cellar/go/1.10/libexec/src/runtime
    141  -compress/flate | /usr/local/Cellar/go/1.10/libexec/src/compress/flate
    142  -compress/gzip | /usr/local/Cellar/go/1.10/libexec/src/compress/gzip
    143  -context | /usr/local/Cellar/go/1.10/libexec/src/context
    144  -encoding/binary | .
    145  -errors | /usr/local/Cellar/go/1.10/libexec/src/errors
    146  -fmt | /usr/local/Cellar/go/1.10/libexec/src/fmt
    147  -go | .
    148  -hash | .
    149  -hash/crc32 | /usr/local/Cellar/go/1.10/libexec/src/hash/crc32
    150  -internal/cpu | /usr/local/Cellar/go/1.10/libexec/src/internal/cpu
    151  -internal/poll | /usr/local/Cellar/go/1.10/libexec/src/runtime
    152  -internal/singleflight | /usr/local/Cellar/go/1.10/libexec/src/internal/singleflight
    153  -internal/testlog | /usr/local/Cellar/go/1.10/libexec/src/internal/testlog
    154  -io | /usr/local/Cellar/go/1.10/libexec/src/io
    155  -io/ioutil | /usr/local/Cellar/go/1.10/libexec/src/io/ioutil
    156  -math | .
    157  -math/rand | /usr/local/Cellar/go/1.10/libexec/src/math/rand
    158  -net | /usr/local/Cellar/go/1.10/libexec/src/net
    159  -os | /usr/local/Cellar/go/1.10/libexec/src/runtime
    160  -os/exec | /usr/local/Cellar/go/1.10/libexec/src/os/exec
    161  -os/signal | /usr/local/Cellar/go/1.10/libexec/src/runtime
    162  -path/filepath | /usr/local/Cellar/go/1.10/libexec/src/path/filepath
    163  -reflect | /usr/local/Cellar/go/1.10/libexec/src/runtime
    164  -runtime | /usr/local/Cellar/go/1.10/libexec/src/runtime
    165  -runtime/debug | /usr/local/Cellar/go/1.10/libexec/src/runtime
    166  -sort | /usr/local/Cellar/go/1.10/libexec/src/sort
    167  -strconv | /usr/local/Cellar/go/1.10/libexec/src/strconv
    168  -strings | /usr/local/Cellar/go/1.10/libexec/src/runtime
    169  -sync | /usr/local/Cellar/go/1.10/libexec/src/runtime
    170  -sync/atomic | /usr/local/Cellar/go/1.10/libexec/src/sync/atomic
    171  -syscall | /usr/local/Cellar/go/1.10/libexec/src/runtime
    172  -time | /usr/local/Cellar/go/1.10/libexec/src/runtime
    173  -unicode | /usr/local/Cellar/go/1.10/libexec/src/unicode
    174  -unicode/utf8 | /usr/local/Cellar/go/1.10/libexec/src/unicode/utf8
    175  -```
    176  - 
    177  -### Compiler information
    178  - 
    179  -Information about the Go compiler used to build the binary can be
    180  -shown by using the `-compiler` flag. It prints the release version
    181  -and the time stamp when the release tag was created in the git tree.
     161 +Name Version Path
     162 +---- ------- ----
     163 +main /Users/ronald/git/go-workspace/src/keybase.io/safetycrew/pplauncher
    182 164   
    183  -```
    184  -$ redress -compiler pplauncher
    185  -Compiler version: go1.10 (2018-02-16T16:05:53Z)
     165 +Standard Library Packages:
     166 +Name Version Path
     167 +---- ------- ----
     168 +bufio /usr/local/Cellar/go/1.10/libexec/src/bufio
     169 +bytes /usr/local/Cellar/go/1.10/libexec/src/runtime
     170 +compress/flate /usr/local/Cellar/go/1.10/libexec/src/compress/flate
     171 +compress/gzip /usr/local/Cellar/go/1.10/libexec/src/compress/gzip
     172 +context /usr/local/Cellar/go/1.10/libexec/src/context
     173 +encoding/binary .
     174 +errors /usr/local/Cellar/go/1.10/libexec/src/errors
     175 +fmt /usr/local/Cellar/go/1.10/libexec/src/fmt
     176 +hash .
     177 +hash/crc32 /usr/local/Cellar/go/1.10/libexec/src/hash/crc32
     178 +internal/cpu /usr/local/Cellar/go/1.10/libexec/src/internal/cpu
     179 +internal/poll /usr/local/Cellar/go/1.10/libexec/src/runtime
     180 +internal/singleflight /usr/local/Cellar/go/1.10/libexec/src/internal/singleflight
     181 +internal/testlog /usr/local/Cellar/go/1.10/libexec/src/internal/testlog
     182 +io /usr/local/Cellar/go/1.10/libexec/src/io
     183 +io/ioutil .
     184 +math .
     185 +math/rand /usr/local/Cellar/go/1.10/libexec/src/math/rand
     186 +net /usr/local/Cellar/go/1.10/libexec/src/net
     187 +os /usr/local/Cellar/go/1.10/libexec/src/runtime
     188 +os/exec /usr/local/Cellar/go/1.10/libexec/src/os/exec
     189 +os/signal /usr/local/Cellar/go/1.10/libexec/src/runtime
     190 +path/filepath /usr/local/Cellar/go/1.10/libexec/src/path/filepath
     191 +reflect /usr/local/Cellar/go/1.10/libexec/src/runtime
     192 +runtime /usr/local/Cellar/go/1.10/libexec/src/runtime
     193 +runtime/debug /usr/local/Cellar/go/1.10/libexec/src/runtime
     194 +sort /usr/local/Cellar/go/1.10/libexec/src/sort
     195 +strconv /usr/local/Cellar/go/1.10/libexec/src/strconv
     196 +strings /usr/local/Cellar/go/1.10/libexec/src/runtime
     197 +sync /usr/local/Cellar/go/1.10/libexec/src/runtime
     198 +sync/atomic /usr/local/Cellar/go/1.10/libexec/src/sync/atomic
     199 +syscall /usr/local/Cellar/go/1.10/libexec/src/runtime
     200 +time /usr/local/Cellar/go/1.10/libexec/src/runtime
     201 +unicode /usr/local/Cellar/go/1.10/libexec/src/unicode
     202 +unicode/utf8 /usr/local/Cellar/go/1.10/libexec/src/unicode/utf8
    186 203  ```
    187 204   
    188 205  ### Extracting types
    189 206   
    190  -*Redress* has multiple flags that can be used to extract different type data.
    191  -Interfaces can be extracted with the `-interface` flag. By default, standard
    192  -library interfaces are filtered out. These can be included by also providing
    193  -the `-std` flag.
     207 +*Redress* has multiple commands that can be used to extract different type data.
     208 +Interfaces can be extracted with the `interface` command. By default, standard
     209 +library and vendor interfaces are filtered out. These can be included by also
     210 +providing the `--std` and `--vendor` flag.
    194 211   
    195 212  ```
    196  -$ redress -interface pplauncher
     213 +% redress types interface pplauncher
    197 214  type error interface {
    198 215   Error() string
    199 216  }
    200  - 
    201 217  type interface {} interface{}
    202  - 
    203 218  type route.Addr interface {
    204 219   Family() int
    205 220  }
    206  - 
    207 221  type route.Message interface {
    208 222   Sys() []route.Sys
    209 223  }
    210  - 
    211 224  type route.Sys interface {
    212 225   SysType() int
    213 226  }
    214  - 
    215 227  type route.binaryByteOrder interface {
    216 228   PutUint16([]uint8, uint16)
    217 229   PutUint32([]uint8, uint32)
    skipped 3 lines
    221 233  }
    222 234  ```
    223 235   
    224  -Structures can be extracted with the `-struct` flag (`redress -struct
    225  -pplauncher`). Same as for interfaces, standard library structures are filtered
    226  -out but can be included by also providing the `-std` flag.
     236 +Structures can be extracted with the `struct` command. Same as with interfaces,
     237 +standard library and vendor structures are filtered out but can be included by
     238 +providing the `--std` or `--vendor` flag.
    227 239   
    228 240  ```
    229  -type main.asset struct{
    230  - bytes []uint8
    231  - info os.FileInfo
     241 +% redress types struct pplauncher
     242 +...
     243 +type main.bintree struct {
     244 + Func func() (*main.asset, error)
     245 + Children map[string]*main.bintree
    232 246  }
     247 +...
    233 248   
    234  -type main.bindataFileInfo struct{
    235  - name string
    236  - size int64
    237  - mode uint32
    238  - modTime time.Time
     249 +type main.asset struct {
     250 + bytes []uint8
     251 + info os.FileInfo
    239 252  }
    240 253   
    241  -type main.bintree struct{
    242  - Func func() (*main.asset, error)
    243  - Children map[string]*main.bintree
     254 +type main.bindataFileInfo struct {
     255 + name string
     256 + size int64
     257 + mode uint32
     258 + modTime time.Time
    244 259  }
     260 +...
    245 261  ```
    246 262   
    247  -Methods for the structure can be shown with the command `redress -struct
    248  --method pplauncher`.
     263 +Methods definitions for the structure is shown by including the `--methods` flag.
    249 264   
    250 265  ```
    251  -type main.asset struct{
     266 +% redress types struct pplauncher --methods
     267 +...
     268 +type main.asset struct {
    252 269   bytes []uint8
    253  - info os.FileInfo
     270 + info os.FileInfo
    254 271  }
    255 272   
    256  -type main.bindataFileInfo struct{
    257  - name string
    258  - size int64
    259  - mode uint32
     273 +type main.bindataFileInfo struct {
     274 + name string
     275 + size int64
     276 + mode uint32
    260 277   modTime time.Time
    261 278  }
    262 279  func (main.bindataFileInfo) IsDir() bool
    skipped 2 lines
    265 282  func (main.bindataFileInfo) Name() string
    266 283  func (main.bindataFileInfo) Size() int64
    267 284  func (main.bindataFileInfo) Sys() interface {}
    268  - 
    269  -type main.bintree struct{
    270  - Func func() (*main.asset, error)
    271  - Children map[string]*main.bintree
    272  -}
     285 +...
    273 286  ```
    274 287   
    275  -It is also possible to print all types in the binary by using the `-type` flag.
    276  -The `-method` flag can also be used to include defined methods.
     288 +It is also possible to print all types in the binary by using the `all` command.
    277 289   
    278 290  ### Estimating source code layout
    279 291   
    280  -One feature of _redress_ is to reconstruct the source code tree layout. This
    281  -can be done by using the `-src` flag. By default, standard library and 3rd
    282  -party packages are excluded but can be included by providing the flags `-std`,
    283  -`-vendor`, and/or `-unknown`.
     292 +One feature of _redress_ is to reconstruct the source code tree layout. This
     293 +can be done by using the `source` command. By default, standard library and 3rd
     294 +party packages are excluded but can be included by providing the flags `--std`,
     295 +`--vendor`, and/or `--unknown` flags.
    284 296   
    285 297  The output includes the package name and its folder location at compile time.
    286 298  For each file, the functions defined within are printed. The output also
    skipped 1 lines
    288 300  *redress* tries to guess the starting and ending line number.
    289 301   
    290 302  ```
    291  -$ redress -src pplauncher
     303 +% redress source pplauncher
    292 304  Package main: /Users/ronald/git/go-workspace/src/keybase.io/safetycrew/pplauncher
    293 305  File: <autogenerated>
    294  - init Lines: 1 to 164 (163)
    295  - (*bindataFileInfo)Name Lines: 1 to 54 (53)
    296  - (*bindataFileInfo)Size Lines: 1 to 57 (56)
    297  - (*bindataFileInfo)Mode Lines: 1 to 60 (59)
    298  - (*bindataFileInfo)ModTime Lines: 1 to 63 (62)
    299  - (*bindataFileInfo)IsDir Lines: 1 to 1 (0)
     306 + init Lines: 1 to 1 (0)
     307 + (*bindataFileInfo)Mode Lines: 1 to 1 (0)
     308 + (*bindataFileInfo)Name Lines: 1 to 1 (0)
     309 + (*bindataFileInfo)ModTime Lines: 1 to 1 (0)
     310 + (*bindataFileInfo)Size Lines: 1 to 1 (0)
    300 311   (*bindataFileInfo)Sys Lines: 1 to 1 (0)
     312 + (*bindataFileInfo)IsDir Lines: 1 to 1 (0)
    301 313  File: bindata.go
    302 314   bindataRead Lines: 21 to 54 (33)
    303 315   bindataFileInfoName Lines: 54 to 57 (3)
    skipped 19 lines
    323 335   autoKillfunc1 Lines: 153 to 163 (10)
    324 336   handleExit Lines: 160 to 169 (9)
    325 337   handleExitfunc1 Lines: 163 to 166 (3)
    326  - main Lines: 169 to 175 (6)
     338 + main Lines: 169 to 178 (9)
    327 339  ```
    328 340   
    329 341  ## Using redress with radare2
    skipped 8 lines
    338 350  `main.main` function recursively.
    339 351   
    340 352  ```
    341  -$ r2 pplauncher
    342  - -- There's no way you could crash radare2. No. Way.
    343  -[0x01055c90]> #!pipe redress
     353 +% r2 pplauncher
     354 + -- radare2 contributes to the One Byte Per Child foundation.
     355 +[0x01055c90]> #!pipe redress r2 init
    344 356  Compiler version: go1.10 (2018-02-16T16:05:53Z)
    345  -40 packages found.
    346  -2659 function symbols found
     357 +39 packages found.
     358 +2943 function symbols found
     359 +Analyzing all init functions.
     360 +Analyzing all main.main.
    347 361  1717 type symbols found
    348 362  ```
    349 363   
    skipped 1 lines
    351 365  flags can be used to print the Go definition for a specific type.
    352 366   
    353 367  ```
    354  -[0x01055c90]> #!pipe redress -h
    355  -Usage of redress:
    356  - -method
    357  - Print type's methods
    358  - -type int
    359  - Lookup the Go definition for a type
    360  - -version
    361  - Print redress version
     368 +[0x01055c90]> #!pipe redress r2 help
     369 +Use redress with in r2.
     370 + 
     371 +Usage:
     372 + redress r2 [command]
     373 + 
     374 +Aliases:
     375 + r2, radare, radare2, r
     376 + 
     377 +Available Commands:
     378 + init Perform the initial analysis
     379 + line Annotate function with source lines.
     380 + strarr Print string array.
     381 + type Print type definition.
     382 + 
     383 +Flags:
     384 + -h, --help help for r2
     385 + 
     386 +Use "redress r2 [command] --help" for more information about a command.
    362 387  ```
    363 388   
    364 389  ### Working with types
    skipped 20 lines
    385 410  0x01116c20 1 sym.type.main.bintree
    386 411  ```
    387 412   
    388  -By executing _redress_ with the `-type` flag and the address, the type definition
    389  -is returned:
     413 +By executing _redress_ with the `type` command and the address, the type
     414 +definition is returned:
    390 415   
    391 416  ```
    392  -:> #!pipe redress -type 0x01116c20
     417 +> #!pipe redress r2 type 0x01116c20
    393 418  type main.bintree struct{
    394 419   Func func() (*main.asset, error)
    395 420   Children map[string]*main.bintree
    skipped 3 lines
    399 424  It is possible to chain the two commands:
    400 425   
    401 426  ```
    402  -:> #!pipe redress -type `f~sym.type.main.bintree~[0]`
     427 +:> #!pipe redress r2 type `f~sym.type.main.bintree~[0]`
    403 428  type main.bintree struct{
    404 429   Func func() (*main.asset, error)
    405 430   Children map[string]*main.bintree
    skipped 3 lines
    409 434  A better way is to define a _radare2_ macro:
    410 435   
    411 436  ```
    412  -:> (type flag,#!pipe redress -type `f~$0~[0]`)
     437 +:> (type flag,#!pipe redress r2 type `f~$0~[0]`)
    413 438  :> .(type sym.type.main.bintree)
    414 439  type main.bintree struct{
    415 440   Func func() (*main.asset, error)
    skipped 1 lines
    417 442  }
    418 443  ```
    419 444   
    420  -The methods for the type can also be included in the output by including the
    421  -`-method` flag. Below a new macro is defined.
    422  - 
    423  -```
    424  -(type+ flag,#!pipe redress -method -type `f~$0~[0]`)
    425  -```
    426  - 
    427  -In the code snippet below, it can be seen that memory for the `exec.Cmd`
    428  -structure is being allocated.
    429  - 
    430  -```
    431  -0x010e5cc5 488d0514b804. lea rax, sym.type.exec.Cmd
    432  -0x010e5ccc 48890424 mov qword [rsp], rax
    433  -0x010e5cd0 e8abb2f2ff call sym.runtime.newobject
    434  -```
    435  - 
    436  -The `exec.Cmd` does not have any methods because they are associated with the
    437  -pointer type (`*exec.Cmd`) for the structure. To get the methods, this type has
    438  -to be used. It can be found by grepping the flags for `exec.Cmd`. _Radare2_
    439  -will replace the "__*__" with a "**_**" in the flag name. Using `_exec.Cmd`
    440  -instead does return the methods.
    441  - 
    442  -```
    443  -:> .(type+ sym.type.exec.Cmd)
    444  -type exec.Cmd struct{
    445  - Path string
    446  - Args []string
    447  - Env []string
    448  - Dir string
    449  - Stdin io.Reader
    450  - Stdout io.Writer
    451  - Stderr io.Writer
    452  - ExtraFiles []*os.File
    453  - SysProcAttr *syscall.SysProcAttr
    454  - Process *os.Process
    455  - ProcessState *os.ProcessState
    456  - ctx context.Context
    457  - lookPathErr error
    458  - finished bool
    459  - childFiles []*os.File
    460  - closeAfterStart []io.Closer
    461  - closeAfterWait []io.Closer
    462  - goroutine []func() error
    463  - errch chan error
    464  - waitDone chan struct {}
    465  -}
    466  -:> f~exec.Cmd
    467  -0x010ff100 1 sym.type._struct___F_uintptr__pw__os.File__c__exec.Cmd
    468  -0x0111ada0 1 sym.type.struct___F_uintptr__pw__os.File__c__exec.Cmd
    469  -0x0112c280 1 sym.type._exec.Cmd
    470  -0x011314e0 1 sym.type.exec.Cmd
    471  -:> .(type+ sym.type._exec.Cmd)
    472  -*exec.Cmd
    473  -func (*exec.Cmd) CombinedOutput()
    474  -func (*exec.Cmd) Output()
    475  -func (*exec.Cmd) Run() error
    476  -func (*exec.Cmd) Start() error
    477  -func (*exec.Cmd) StderrPipe()
    478  -func (*exec.Cmd) StdinPipe()
    479  -func (*exec.Cmd) StdoutPipe()
    480  -func (*exec.Cmd) Wait() error
    481  -func (*exec.Cmd) argv()
    482  -func (*exec.Cmd) closeDescriptors()
    483  -func (*exec.Cmd) envv()
    484  -func (*exec.Cmd) stderr()
    485  -func (*exec.Cmd) stdin()
    486  -func (*exec.Cmd) stdout()
    487  -func (*exec.Cmd) writerDescriptor()
    488  -```
    489  - 
  • ■ ■ ■ ■ ■ ■
    exp.go
     1 +// Copyright 2021 The GoRE Authors. All rights reserved.
     2 +// Use of this source code is governed by the license that
     3 +// can be found in the LICENSE file.
     4 + 
     5 +package main
     6 + 
     7 +import (
     8 + "github.com/spf13/cobra"
     9 +)
     10 + 
     11 +var expCmd = &cobra.Command{
     12 + Use: "experiment",
     13 + Aliases: []string{"exp", "x"},
     14 + Short: "Experimental functionality",
     15 + Long: expHelp,
     16 + Hidden: true,
     17 +}
     18 + 
     19 +func init() {
     20 + // Register the command.
     21 + rootCmd.AddCommand(expCmd)
     22 +}
     23 + 
     24 +const expHelp = `Experimental functionality
     25 + 
     26 +The following commands are experimental and may change or removed
     27 +in the future.
     28 +`
     29 + 
  • ■ ■ ■ ■ ■
    go.mod
    skipped 3 lines
    4 4   
    5 5  require (
    6 6   github.com/TcM1911/r2g2 v0.3.2
    7  - github.com/davecgh/go-spew v1.1.1 // indirect
    8  - github.com/goretk/gore v0.8.18
     7 + github.com/cheynewallace/tabby v1.1.1
     8 + github.com/goretk/gore v0.10.0
     9 + github.com/spf13/cobra v1.2.1
     10 + golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
     11 + golang.org/x/mod v0.5.1 // indirect
    9 12  )
    10 13   
     14 +// This is used during development and disabled for release builds.
     15 +// replace github.com/goretk/gore => ./gore
     16 + 
  • ■ ■ ■ ■ ■ ■
    go.sum
     1 +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
     2 +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
     3 +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
     4 +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
     5 +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
     6 +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
     7 +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
     8 +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
     9 +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
     10 +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
     11 +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
     12 +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
     13 +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
     14 +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
     15 +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
     16 +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
     17 +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
     18 +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
     19 +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
     20 +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
     21 +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
     22 +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
     23 +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
     24 +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
     25 +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
     26 +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
     27 +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
     28 +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
     29 +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
     30 +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
     31 +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
     32 +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
     33 +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
     34 +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
     35 +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
     36 +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
     37 +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
     38 +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
     39 +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
     40 +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
     41 +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
    1 42  github.com/TcM1911/r2g2 v0.3.2 h1:v+MaRN0sAGZsVP3+CC8WlL1psWZfAQwL5oTzSeF0K0s=
    2 43  github.com/TcM1911/r2g2 v0.3.2/go.mod h1:PkHPKq4ChUQ67gkJNZDpIFukIClcFtSyBwsqyyF+ELA=
     44 +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
     45 +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
     46 +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
     47 +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
     48 +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
     49 +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
     50 +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
     51 +github.com/cheynewallace/tabby v1.1.1 h1:JvUR8waht4Y0S3JF17G6Vhyt+FRhnqVCkk8l4YrOU54=
     52 +github.com/cheynewallace/tabby v1.1.1/go.mod h1:Pba/6cUL8uYqvOc9RkyvFbHGrQ9wShyrn6/S/1OYVys=
     53 +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
     54 +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
     55 +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
     56 +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
     57 +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
     58 +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
     59 +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
     60 +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
     61 +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
     62 +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
    3 63  github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
    4 64  github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
    5 65  github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
    6  -github.com/goretk/gore v0.8.18 h1:o+FnKF1c0ukPS14dw16BN34X77siMZibLpb4fyqxFOs=
    7  -github.com/goretk/gore v0.8.18/go.mod h1:pswwr4VKZRoqrVzlvEU53Tg9i/RTPCf9ipkfP0jP9eE=
     66 +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
     67 +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
     68 +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
     69 +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
     70 +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
     71 +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
     72 +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
     73 +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
     74 +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
     75 +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
     76 +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
     77 +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
     78 +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
     79 +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
     80 +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
     81 +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
     82 +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
     83 +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
     84 +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
     85 +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
     86 +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
     87 +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
     88 +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
     89 +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
     90 +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
     91 +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
     92 +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
     93 +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
     94 +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
     95 +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
     96 +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
     97 +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
     98 +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
     99 +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
     100 +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
     101 +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
     102 +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
     103 +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
     104 +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
     105 +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
     106 +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
     107 +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
     108 +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
     109 +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
     110 +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
     111 +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
     112 +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
     113 +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
     114 +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
     115 +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
     116 +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
     117 +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
     118 +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
     119 +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
     120 +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
     121 +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
     122 +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
     123 +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
     124 +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
     125 +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
     126 +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
     127 +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
     128 +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
     129 +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
     130 +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
     131 +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
     132 +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
     133 +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
     134 +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
     135 +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
     136 +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
     137 +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
     138 +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
     139 +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
     140 +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
     141 +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
     142 +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
     143 +github.com/goretk/gore v0.10.0 h1:ewk402Z0cBTSe+DB5ooBa8CsEAnEWE+E8cbJS7heqyM=
     144 +github.com/goretk/gore v0.10.0/go.mod h1:cQa3kuurmyYBGPAlfeENhSm5tjdgoLP6Fs3jqJM8ayU=
     145 +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
     146 +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
     147 +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
     148 +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
     149 +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
     150 +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
     151 +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
     152 +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
     153 +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
     154 +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
     155 +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
     156 +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
     157 +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
     158 +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
     159 +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
     160 +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
     161 +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
     162 +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
     163 +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
     164 +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
     165 +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
     166 +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
     167 +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
     168 +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
     169 +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
     170 +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
     171 +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
     172 +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
     173 +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
     174 +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
     175 +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
     176 +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
     177 +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
     178 +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
     179 +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
     180 +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
    8 181  github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
    9 182  github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
     183 +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
     184 +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
     185 +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
     186 +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
     187 +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
     188 +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
     189 +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
     190 +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
     191 +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
     192 +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
     193 +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
     194 +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
     195 +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
     196 +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
     197 +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
     198 +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
     199 +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
     200 +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
    10 201  github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
    11 202  github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
     203 +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
     204 +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
     205 +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
     206 +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
     207 +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
     208 +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
     209 +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
     210 +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
     211 +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
     212 +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
     213 +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
     214 +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
     215 +github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw=
     216 +github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
     217 +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
     218 +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
     219 +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
     220 +github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
    12 221  github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
    13  -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
     222 +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
     223 +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
    14 224  github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
     225 +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
     226 +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
     227 +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
     228 +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
     229 +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
     230 +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
     231 +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
     232 +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
     233 +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
     234 +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
     235 +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
     236 +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
     237 +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
     238 +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
     239 +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
     240 +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
     241 +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
     242 +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
     243 +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
     244 +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
     245 +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
     246 +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
     247 +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
     248 +golang.org/x/arch v0.0.0-20201207233722-1e68675e650f/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
     249 +golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU=
     250 +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
     251 +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
     252 +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
     253 +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
     254 +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
     255 +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
     256 +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
     257 +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
     258 +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
     259 +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
     260 +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
     261 +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
     262 +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
     263 +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
     264 +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
     265 +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
     266 +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
     267 +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
     268 +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
     269 +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
     270 +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
     271 +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
     272 +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
     273 +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
     274 +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
     275 +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
     276 +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
     277 +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
     278 +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
     279 +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
     280 +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
     281 +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
     282 +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
     283 +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
     284 +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
     285 +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
     286 +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
     287 +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
     288 +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
     289 +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
     290 +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
     291 +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
     292 +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
     293 +golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
     294 +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
     295 +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
     296 +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
     297 +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
     298 +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
     299 +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
     300 +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
     301 +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
     302 +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
     303 +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
     304 +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
     305 +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
     306 +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
     307 +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
     308 +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
     309 +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
     310 +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
     311 +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
     312 +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
     313 +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
     314 +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
     315 +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
     316 +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
     317 +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
     318 +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
     319 +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
     320 +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
     321 +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
     322 +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
     323 +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
     324 +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
     325 +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
     326 +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
     327 +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
     328 +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
     329 +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
     330 +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
     331 +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
     332 +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
     333 +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
     334 +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
     335 +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
     336 +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
     337 +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
     338 +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
     339 +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
     340 +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
     341 +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
     342 +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
     343 +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
     344 +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
     345 +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
     346 +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
     347 +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
     348 +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
     349 +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
     350 +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
     351 +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
     352 +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
     353 +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
     354 +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
     355 +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
     356 +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
     357 +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
     358 +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     359 +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     360 +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     361 +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     362 +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     363 +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     364 +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     365 +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     366 +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     367 +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     368 +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     369 +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     370 +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     371 +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     372 +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     373 +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     374 +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     375 +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     376 +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     377 +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     378 +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     379 +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     380 +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     381 +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     382 +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     383 +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     384 +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     385 +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     386 +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     387 +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     388 +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     389 +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     390 +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     391 +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     392 +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     393 +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     394 +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
     395 +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
     396 +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
     397 +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
     398 +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
     399 +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
     400 +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
     401 +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
     402 +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
     403 +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
     404 +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
     405 +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
     406 +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
     407 +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
     408 +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
     409 +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
     410 +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
     411 +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
     412 +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
     413 +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
     414 +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
     415 +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
     416 +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
     417 +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
     418 +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
     419 +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
     420 +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
     421 +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
     422 +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
     423 +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
     424 +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
     425 +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
     426 +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
     427 +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
     428 +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
     429 +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
     430 +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
     431 +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
     432 +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
     433 +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
     434 +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
     435 +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
     436 +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
     437 +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
     438 +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
     439 +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
     440 +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
     441 +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
     442 +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
     443 +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
     444 +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
     445 +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
     446 +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
     447 +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
     448 +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
     449 +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
     450 +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
     451 +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
     452 +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
     453 +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
     454 +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
     455 +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
     456 +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
     457 +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
     458 +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
     459 +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
     460 +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
     461 +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
     462 +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
     463 +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
     464 +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
     465 +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
     466 +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
     467 +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
     468 +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
     469 +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
     470 +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
     471 +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
     472 +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
     473 +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
     474 +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
     475 +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
     476 +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
     477 +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
     478 +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
     479 +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
     480 +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
     481 +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
     482 +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
     483 +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
     484 +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
     485 +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
     486 +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
     487 +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
     488 +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
     489 +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
     490 +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
     491 +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
     492 +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
     493 +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
     494 +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
     495 +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
     496 +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
     497 +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
     498 +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
     499 +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
     500 +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
     501 +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
     502 +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
     503 +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
     504 +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
     505 +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
     506 +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
     507 +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
     508 +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
     509 +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
     510 +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
     511 +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
     512 +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
     513 +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
     514 +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
     515 +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
     516 +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
     517 +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
     518 +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
     519 +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
     520 +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
     521 +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
     522 +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
     523 +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
     524 +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
     525 +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
     526 +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
     527 +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
     528 +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
     529 +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
     530 +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
     531 +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
     532 +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
     533 +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
     534 +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
     535 +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
     536 +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
     537 +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
     538 +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
     539 +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
     540 +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
     541 +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
     542 +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
     543 +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
     544 +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
     545 +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
     546 +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
     547 +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
     548 +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
     549 +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
     550 +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
     551 +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
     552 +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
     553 +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
     554 +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
     555 +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
     556 +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
     557 +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
     558 +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
     559 +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
     560 +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
     561 +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
     562 +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
    15 563  gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
    16  -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
     564 +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
     565 +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
     566 +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
    17 567  gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
     568 +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
     569 +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
     570 +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
     571 +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
     572 +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
     573 +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
     574 +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
     575 +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
     576 +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
     577 +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
     578 +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
     579 +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
     580 +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
     581 +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
     582 +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
     583 +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
     584 +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
    18 585   
  • ■ ■ ■ ■ ■
    gore
     1 +[email protected]:goretk/gore.git:73e743abde3df946cc3e8480aa41e0abd6bba701
  • ■ ■ ■ ■ ■ ■
    info.go
     1 +// Copyright 2021 The GoRE Authors. All rights reserved.
     2 +// Use of this source code is governed by the license that
     3 +// can be found in the LICENSE file.
     4 + 
     5 +package main
     6 + 
     7 +import (
     8 + "fmt"
     9 + "os"
     10 + "path/filepath"
     11 + "strings"
     12 + 
     13 + "github.com/cheynewallace/tabby"
     14 + gore "github.com/goretk/gore"
     15 + "github.com/spf13/cobra"
     16 +)
     17 + 
     18 +func init() {
     19 + infoCMD := &cobra.Command{
     20 + Use: "info path/to/go/file",
     21 + Aliases: []string{"metadata", "i"},
     22 + Short: "Print summary information.",
     23 + Args: cobra.ExactArgs(1),
     24 + Run: func(cmd *cobra.Command, args []string) {
     25 + listInfo(args[0])
     26 + },
     27 + }
     28 + 
     29 + expCmd.AddCommand(&cobra.Command{
     30 + Use: "mod /path/to/go/file",
     31 + Aliases: []string{"m"},
     32 + Short: "Display go mod info.",
     33 + Args: cobra.ExactArgs(1),
     34 + Run: func(cmd *cobra.Command, args []string) {
     35 + listModInfo(args[0])
     36 + },
     37 + })
     38 + 
     39 + rootCmd.AddCommand(infoCMD)
     40 +}
     41 + 
     42 +func listInfo(fileStr string) {
     43 + fp, err := filepath.Abs(fileStr)
     44 + if err != nil {
     45 + fmt.Fprintf(os.Stderr, "Failed to parse the filepath: %s.\n", err)
     46 + os.Exit(1)
     47 + }
     48 + 
     49 + f, err := gore.Open(fp)
     50 + if err != nil {
     51 + fmt.Fprintf(os.Stderr, "Error when opening the file: %s.\n", err)
     52 + os.Exit(1)
     53 + }
     54 + defer f.Close()
     55 + 
     56 + t := tabby.New()
     57 + 
     58 + t.AddLine("OS", f.FileInfo.OS)
     59 + t.AddLine("Arch", f.FileInfo.Arch)
     60 + 
     61 + if comp, err := f.GetCompilerVersion(); err == nil {
     62 + t.AddLine("Compiler", fmt.Sprintf("%s (%s)", strings.TrimPrefix(comp.Name, "go"), strings.Split(comp.Timestamp, "T")[0]))
     63 + }
     64 + 
     65 + if f.BuildID != "" {
     66 + t.AddLine("Build ID", f.BuildID)
     67 + }
     68 + 
     69 + if root, err := f.GetGoRoot(); err == nil {
     70 + t.AddLine("GoRoot", root)
     71 + }
     72 + 
     73 + if pkg, err := f.GetPackages(); err == nil {
     74 + for _, p := range pkg {
     75 + if p.Name == "main" {
     76 + t.AddLine("Main root", p.Filepath)
     77 + break
     78 + }
     79 + }
     80 + t.AddLine("# main", len(pkg))
     81 + 
     82 + std, _ := f.GetSTDLib()
     83 + t.AddLine("# std", len(std))
     84 + 
     85 + ven, _ := f.GetVendors()
     86 + t.AddLine("# vendor", len(ven))
     87 + 
     88 + unk, _ := f.GetUnknown()
     89 + if len(unk) != 0 {
     90 + t.AddLine("# unknown", len(unk))
     91 + }
     92 + }
     93 + 
     94 + t.Print()
     95 +}
     96 + 
     97 +func listModInfo(fileStr string) {
     98 + fp, err := filepath.Abs(fileStr)
     99 + if err != nil {
     100 + fmt.Fprintf(os.Stderr, "Failed to parse the filepath: %s.\n", err)
     101 + os.Exit(1)
     102 + }
     103 + 
     104 + f, err := gore.Open(fp)
     105 + if err != nil {
     106 + fmt.Fprintf(os.Stderr, "Error when opening the file: %s.\n", err)
     107 + os.Exit(1)
     108 + }
     109 + defer f.Close()
     110 + 
     111 + if f.BuildInfo == nil {
     112 + fmt.Fprintf(os.Stderr, "No build info found in the file.\n")
     113 + return
     114 + }
     115 + 
     116 + if f.BuildInfo.ModInfo == nil {
     117 + fmt.Fprintf(os.Stderr, "No mod info found in the file.\n")
     118 + return
     119 + }
     120 + 
     121 + mod := f.BuildInfo.ModInfo
     122 + 
     123 + t := tabby.New()
     124 + 
     125 + t.AddHeader("Type", "Name", "Version", "Replaced by", "Hash")
     126 + 
     127 + t.AddLine("main", mod.Main.Path, mod.Main.Version, "", mod.Main.Sum)
     128 + 
     129 + for _, m := range mod.Deps {
     130 + if m.Replace != nil {
     131 + t.AddLine("dep", m.Path, m.Version, m.Replace.Path, m.Sum)
     132 + t.AddLine("replacement", m.Replace.Path, m.Replace.Version, "", m.Sum)
     133 + } else {
     134 + t.AddLine("dep", m.Path, m.Version, "", m.Sum)
     135 + }
     136 + }
     137 + t.Print()
     138 + fmt.Printf("\n")
     139 +}
     140 + 
  • ■ ■ ■ ■ ■ ■
    main.go
    1  -// Copyright 2019 The GoRE.tk Authors. All rights reserved.
     1 +// Copyright 2019-2021 The GoRE Authors. All rights reserved.
    2 2  // Use of this source code is governed by the license that
    3 3  // can be found in the LICENSE file.
    4 4   
    5 5  package main
    6 6   
    7 7  import (
    8  - "flag"
    9 8   "fmt"
     9 + "os"
    10 10   
    11  - "github.com/TcM1911/r2g2"
     11 + "github.com/cheynewallace/tabby"
     12 + "github.com/spf13/cobra"
    12 13  )
    13 14   
    14 15  const (
    15  - assumedGoVersion = "go1.12"
     16 + assumedGoVersion = "go1.16"
    16 17  )
    17 18   
    18  -type option struct {
    19  - printPackages *bool
    20  - printStdLibPackages *bool
    21  - printVendorPackages *bool
    22  - printUnknownPackages *bool
    23  - includeFilepath *bool
    24  - printSourceTree *bool
    25  - printTypes *bool
    26  - printStructs *bool
    27  - printMethods *bool
    28  - printIntefaces *bool
    29  - lookupType *int
    30  - printCompiler *bool
    31  - printVersion *bool
    32  - resolveStrSlice *bool
    33  - forceVersion *string
    34  - srcLine *bool
    35  -}
    36  - 
    37  -// This is set at compile time.
     19 +// These are set at compile time.
    38 20  var redressVersion string
     21 +var goreVersion string
     22 +var compilerVersion string
    39 23   
    40  -var options option
     24 +func main() {
     25 + if err := rootCmd.Execute(); err != nil {
     26 + fmt.Fprintln(os.Stderr, err)
     27 + os.Exit(1)
     28 + }
     29 +}
     30 + 
     31 +var rootCmd = &cobra.Command{
     32 + Use: "redress",
     33 + Short: banner,
     34 +}
    41 35   
    42 36  func init() {
    43  - if r2g2.CheckForR2Pipe() {
    44  - options.lookupType = flag.Int("type", 0, "Lookup the Go definition for a type")
    45  - options.resolveStrSlice = flag.Bool("str", false, "Print slice of strings at offset")
    46  - options.srcLine = flag.Bool("line", false, "Add source code line information as comments for the function.")
    47  - } else {
    48  - options.printPackages = flag.Bool("pkg", false, "List packages")
    49  - options.printStdLibPackages = flag.Bool("std", false, "Include standard library packages")
    50  - options.printVendorPackages = flag.Bool("vendor", false, "Include vendor packages")
    51  - options.printUnknownPackages = flag.Bool("unknown", false, "Include unknown packages")
    52  - options.includeFilepath = flag.Bool("filepath", false, "Include file path for packages")
    53  - options.printSourceTree = flag.Bool("src", false, "Print source tree")
    54  - options.printTypes = flag.Bool("type", false, "Print all type information")
    55  - options.printStructs = flag.Bool("struct", false, "Print structs")
    56  - options.printIntefaces = flag.Bool("interface", false, "Print interfaces")
    57  - options.printCompiler = flag.Bool("compiler", false, "Print information")
    58  - options.forceVersion = flag.String("force-version", "", "Forcing and using the given version when analyzing")
    59  - }
    60  - options.printMethods = flag.Bool("method", false, "Print type's methods")
    61  - options.printVersion = flag.Bool("version", false, "Print redress version")
    62  - flag.Parse()
     37 + rootCmd.AddCommand(&cobra.Command{
     38 + Use: "version",
     39 + Short: "Display redress version information.",
     40 + Run: func(cmd *cobra.Command, args []string) {
     41 + t := tabby.New()
     42 + t.AddLine("Version:", redressVersion)
     43 + t.AddLine("GoRE:", goreVersion)
     44 + t.AddLine("Go:", compilerVersion)
     45 + fmt.Println(banner)
     46 + t.Print()
     47 + },
     48 + })
    63 49  }
    64 50   
    65  -func main() {
    66  - if *options.printVersion {
    67  - fmt.Printf("Redress version: %s\n", redressVersion)
    68  - return
    69  - }
    70  - if r2g2.CheckForR2Pipe() {
    71  - r2Exec()
    72  - } else {
    73  - standalone()
    74  - }
    75  -}
     51 +const banner = `______ _
     52 +| ___ \ | |
     53 +| |_/ /___ __| |_ __ ___ ___ ___
     54 +| // _ \/ _ | '__/ _ / __/ __|
     55 +| |\ | __| (_| | | | __\__ \__ \
     56 +\_| \_\___|\__,_|_| \___|___|___/
     57 +
     58 +`
    76 59   
  • ■ ■ ■ ■ ■ ■
    pkg.go
     1 +// Copyright 2021 The GoRE Authors. All rights reserved.
     2 +// Use of this source code is governed by the license that
     3 +// can be found in the LICENSE file.
     4 +package main
     5 + 
     6 +import (
     7 + "fmt"
     8 + "os"
     9 + "path/filepath"
     10 + "sort"
     11 + "strings"
     12 + 
     13 + "github.com/cheynewallace/tabby"
     14 + gore "github.com/goretk/gore"
     15 + "github.com/spf13/cobra"
     16 +)
     17 + 
     18 +func init() {
     19 + // Flags
     20 + var includeSTD bool
     21 + var includeVendor bool
     22 + var includeUnknown bool
     23 + var includeFilepath bool
     24 + 
     25 + pkgCmd := &cobra.Command{
     26 + Use: "packages path/to/go/file",
     27 + Aliases: []string{"pkg", "pkgs", "p"},
     28 + Short: "List packages.",
     29 + Long: longPkgHelp,
     30 + Args: cobra.ExactArgs(1),
     31 + Run: func(cmd *cobra.Command, args []string) {
     32 + listPackages(args[0], listPackagesOptions{
     33 + std: includeSTD,
     34 + vend: includeVendor,
     35 + unk: includeUnknown,
     36 + fp: includeFilepath,
     37 + })
     38 + },
     39 + }
     40 + 
     41 + pkgCmd.Flags().BoolVarP(&includeSTD, "std", "s", false, "Include standard library packages.")
     42 + pkgCmd.Flags().BoolVarP(&includeVendor, "vendor", "v", false, "Include 3rd party/vendor packages.")
     43 + pkgCmd.Flags().BoolVarP(&includeUnknown, "unknown", "u", false, "Include unidentified packages.")
     44 + pkgCmd.Flags().BoolVarP(&includeFilepath, "filepath", "f", false, "Include the package's filepath.")
     45 + 
     46 + rootCmd.AddCommand(pkgCmd)
     47 +}
     48 + 
     49 +type listPackagesOptions struct {
     50 + std bool
     51 + vend bool
     52 + unk bool
     53 + fp bool
     54 +}
     55 + 
     56 +func listPackages(fileStr string, opts listPackagesOptions) {
     57 + fp, err := filepath.Abs(fileStr)
     58 + if err != nil {
     59 + fmt.Fprintf(os.Stderr, "Failed to parse the filepath: %s.\n", err)
     60 + os.Exit(1)
     61 + }
     62 + 
     63 + f, err := gore.Open(fp)
     64 + if err != nil {
     65 + fmt.Fprintf(os.Stderr, "Error when opening the file: %s.\n", err)
     66 + os.Exit(1)
     67 + }
     68 + defer f.Close()
     69 + 
     70 + packages, err := f.GetPackages()
     71 + if err != nil {
     72 + fmt.Fprintf(os.Stderr, "Error when parsing packages: %s.\n", err)
     73 + os.Exit(1)
     74 + }
     75 + printPackages("Packages", packages, opts.fp)
     76 + 
     77 + if opts.vend {
     78 + // Err check not needed since the parsing was has already been checked.
     79 + vn, _ := f.GetVendors()
     80 + printPackages("Vendors", vn, opts.fp)
     81 + }
     82 + 
     83 + if opts.std {
     84 + std, _ := f.GetSTDLib()
     85 + printPackages("Standard Library Packages", std, opts.fp)
     86 + }
     87 + 
     88 + if opts.unk {
     89 + unk, _ := f.GetUnknown()
     90 + printPackages("Unknown Packages", unk, opts.fp)
     91 + }
     92 +}
     93 + 
     94 +func printPackages(header string, pkgs []*gore.Package, fp bool) {
     95 + fmt.Printf("%s:\n", header)
     96 + sort.Slice(pkgs, func(i, j int) bool {
     97 + return pkgs[i].Name < pkgs[j].Name
     98 + })
     99 + 
     100 + t := tabby.New()
     101 + if fp {
     102 + t.AddHeader("Name", "Version", "Path")
     103 + } else {
     104 + t.AddHeader("Name", "Version")
     105 + }
     106 + 
     107 + for _, p := range pkgs {
     108 + var ver string
     109 + // In Go mod projects, the version is appended at the end of
     110 + // the file path string separated by a "@" character.
     111 + i := strings.LastIndex(p.Filepath, "@")
     112 + if i != -1 && i != len(p.Filepath)+1 {
     113 + ver = strings.Split(p.Filepath[i+1:], "/")[0]
     114 + }
     115 + 
     116 + if fp {
     117 + t.AddLine(p.Name, ver, p.Filepath)
     118 + } else {
     119 + t.AddLine(p.Name, ver)
     120 + }
     121 + }
     122 + t.Print()
     123 + fmt.Printf("\n")
     124 +}
     125 + 
     126 +const longPkgHelp = `List Packages
     127 + 
     128 +The different Go packages used in the binary is extracted. Redress tries by
     129 +default to only display the main package and related packages and skips
     130 +standard library and 3rd party library packages. Sometimes though, redress
     131 +fails to classify a package. In this case, the unclassified packages can be
     132 +printed by also provide the unknown flag.
     133 + 
     134 +To also include the standard library packages, use the standard library flag.
     135 + 
     136 +For 3rd party packages, use the vendor flag.
     137 + 
     138 +The folder locations for the packages can also be included by using the
     139 +filepath flag.
     140 +`
     141 + 
  • ■ ■ ■ ■ ■
    r2.go
    1  -// Copyright 2019 The GoRE.tk Authors. All rights reserved.
     1 +// Copyright 2019-2021 The GoRE Authors. All rights reserved.
    2 2  // Use of this source code is governed by the license that
    3 3  // can be found in the LICENSE file.
    4 4   
    skipped 3 lines
    8 8   "bytes"
    9 9   "encoding/base64"
    10 10   "encoding/binary"
    11  - "flag"
    12 11   "fmt"
    13 12   "io"
     13 + "os"
    14 14   "reflect"
    15 15   "strconv"
    16 16   "strings"
    17 17   
    18 18   "github.com/TcM1911/r2g2"
    19 19   gore "github.com/goretk/gore"
     20 + "github.com/spf13/cobra"
    20 21  )
    21 22   
    22 23  func cleanupName(old string) string {
    23  - newString := strings.Replace(old, " ", "_", -1)
    24  - newString = strings.Replace(newString, "-", "_", -1)
    25  - newString = strings.Replace(newString, ";", "_", -1)
    26  - return newString
     24 + replacer := strings.NewReplacer(
     25 + " ", "_",
     26 + "-", "_",
     27 + ";", "_",
     28 + "/", "_",
     29 + "@", "_",
     30 + )
     31 + return replacer.Replace(old)
     32 +}
     33 + 
     34 +func init() {
     35 + r2Cmd := &cobra.Command{
     36 + Use: "r2",
     37 + Aliases: []string{"radare", "radare2", "r"},
     38 + Short: "Use redress with in r2.",
     39 + // Long: longR2Help,
     40 + }
     41 + 
     42 + var useComment bool
     43 + srcCMD := &cobra.Command{
     44 + Use: "line",
     45 + Short: "Annotate function with source lines.",
     46 + Args: cobra.NoArgs,
     47 + Run: func(cmd *cobra.Command, args []string) {
     48 + if !r2g2.CheckForR2Pipe() {
     49 + fmt.Println("This command can only be executed from within radare2.")
     50 + os.Exit(1)
     51 + }
     52 + annotateWithSourceLine(useComment)
     53 + },
     54 + }
     55 + srcCMD.Flags().BoolVarP(&useComment, "comment", "c", false, "Use comments instead of flags.")
     56 + 
     57 + r2Cmd.AddCommand(srcCMD)
     58 + 
     59 + typCMD := &cobra.Command{
     60 + Use: "type",
     61 + Short: "Print type definition.",
     62 + Args: cobra.ExactArgs(1),
     63 + Run: func(cmd *cobra.Command, args []string) {
     64 + if !r2g2.CheckForR2Pipe() {
     65 + fmt.Println("This command can only be executed from within radare2.")
     66 + return
     67 + }
     68 + addr, err := strconv.ParseUint(args[0], 0, strconv.IntSize)
     69 + if err != nil {
     70 + fmt.Printf("Bad address format: %s.\n", err)
     71 + return
     72 + }
     73 + resolveTypeAt(addr)
     74 + },
     75 + }
     76 + r2Cmd.AddCommand(typCMD)
     77 + 
     78 + strArrCMD := &cobra.Command{
     79 + Use: "strarr offset length",
     80 + Short: "Print string array.",
     81 + Args: cobra.ExactArgs(2),
     82 + Run: func(cmd *cobra.Command, args []string) {
     83 + if !r2g2.CheckForR2Pipe() {
     84 + fmt.Println("This command can only be executed from within radare2.")
     85 + return
     86 + }
     87 + 
     88 + addr, err := strconv.ParseUint(args[0], 0, strconv.IntSize)
     89 + if err != nil {
     90 + fmt.Printf("Bad address format: %s.\n", err)
     91 + return
     92 + }
     93 + 
     94 + length, err := strconv.ParseUint(args[1], 0, strconv.IntSize)
     95 + if err != nil {
     96 + fmt.Printf("Bad length format: %s.\n", err)
     97 + return
     98 + }
     99 + 
     100 + extractStringSlice(addr, length)
     101 + },
     102 + }
     103 + r2Cmd.AddCommand(strArrCMD)
     104 + 
     105 + intCMD := &cobra.Command{
     106 + Use: "init",
     107 + Short: "Perform the initial analysis",
     108 + Aliases: []string{"analyze", "aaa"},
     109 + Args: cobra.NoArgs,
     110 + Run: func(cmd *cobra.Command, args []string) {
     111 + if !r2g2.CheckForR2Pipe() {
     112 + fmt.Println("This command can only be executed from within radare2.")
     113 + return
     114 + }
     115 + 
     116 + initAnal()
     117 + },
     118 + }
     119 + r2Cmd.AddCommand(intCMD)
     120 + 
     121 + rootCmd.AddCommand(r2Cmd)
     122 +}
     123 + 
     124 +func extractStringSlice(addr, length uint64) {
     125 + // Ensure locations is taken from the pipe.
     126 + r2, err := r2g2.OpenPipe()
     127 + if err != nil {
     128 + fmt.Println("Error:", err)
     129 + return
     130 + }
     131 + of, err := r2.GetActiveOpenFile()
     132 + if err != nil {
     133 + fmt.Println("Error when getting current open file:", err)
     134 + return
     135 + }
     136 + 
     137 + file, err := gore.Open(of.Path)
     138 + if err != nil {
     139 + fmt.Println("Error when opening the file:", err)
     140 + return
     141 + }
     142 + defer file.Close()
     143 + 
     144 + printStringSlice(file, addr, length)
    27 145  }
    28 146   
    29  -func r2Exec() {
     147 +func resolveTypeAt(addr uint64) {
     148 + // Ensure locations is taken from the pipe.
     149 + r2, err := r2g2.OpenPipe()
     150 + if err != nil {
     151 + fmt.Println("Error:", err)
     152 + return
     153 + }
     154 + of, err := r2.GetActiveOpenFile()
     155 + if err != nil {
     156 + fmt.Println("Error when getting current open file:", err)
     157 + return
     158 + }
     159 + 
     160 + file, err := gore.Open(of.Path)
     161 + if err != nil {
     162 + fmt.Println("Error when opening the file:", err)
     163 + return
     164 + }
     165 + defer file.Close()
     166 + 
     167 + lookupType(file, addr)
     168 +}
     169 + 
     170 +func annotateWithSourceLine(useComment bool) {
    30 171   // Ensure locations is taken from the pipe.
    31 172   r2, err := r2g2.OpenPipe()
    32 173   if err != nil {
    skipped 14 lines
    47 188   defer file.Close()
    48 189   
    49 190   // Add source code line info
    50  - if *options.srcLine {
    51  - srcLineInfo(r2, file)
     191 + srcLineInfo(r2, file, useComment)
     192 +}
     193 + 
     194 +func initAnal() {
     195 + // Ensure locations is taken from the pipe.
     196 + r2, err := r2g2.OpenPipe()
     197 + if err != nil {
     198 + fmt.Println("Error:", err)
    52 199   return
    53 200   }
    54  - 
    55  - // Lookup type?
    56  - if *options.lookupType != 0 {
    57  - lookupType(file, uint64(*options.lookupType))
     201 + of, err := r2.GetActiveOpenFile()
     202 + if err != nil {
     203 + fmt.Println("Error when getting current open file:", err)
    58 204   return
    59 205   }
    60 206   
    61  - // Print a string slice
    62  - if *options.resolveStrSlice {
    63  - args := flag.Args()
    64  - if len(args) != 2 {
    65  - fmt.Println("2 arguments are required. Address and slice length")
    66  - return
    67  - }
    68  - address, err := strconv.ParseUint(args[0], 0, 32)
    69  - if err != nil {
    70  - fmt.Println("Failed to parse address argument:", err)
    71  - return
    72  - }
    73  - length, err := strconv.ParseUint(args[1], 0, 32)
    74  - if err != nil {
    75  - fmt.Println("Failed to parse length argument:", err)
    76  - return
    77  - }
    78  - printStringSlice(file, address, length)
     207 + file, err := gore.Open(of.Path)
     208 + if err != nil {
     209 + fmt.Println("Error when opening the file:", err)
    79 210   return
    80 211   }
     212 + defer file.Close()
    81 213   
    82 214   // Get compiler version
    83 215   v, err := file.GetCompilerVersion()
    skipped 16 lines
    100 232   vendors, _ := file.GetVendors()
    101 233   std, _ := file.GetSTDLib()
    102 234   unknown, _ := file.GetUnknown()
     235 + generated, _ := file.GetGeneratedPackages()
    103 236   
    104 237   pkgs = append(pkgs, vendors...)
    105 238   pkgs = append(pkgs, std...)
    106 239   pkgs = append(pkgs, unknown...)
     240 + pkgs = append(pkgs, generated...)
    107 241   
    108 242   fmt.Printf("%d packages found.\n", len(pkgs))
    109 243   applyFuncSymbols(pkgs, r2)
    skipped 66 lines
    176 310   default:
    177 311   fmt.Println(typ.String())
    178 312   }
    179  - if *options.printMethods && len(typ.Methods) != 0 {
    180  - fmt.Println(gore.MethodDef(typ))
    181  - }
    182 313   }
    183 314  }
    184 315   
    skipped 38 lines
    223 354   return a, err
    224 355  }
    225 356   
    226  -func srcLineInfo(r2 *r2g2.Client, file *gore.GoFile) {
     357 +func srcLineInfo(r2 *r2g2.Client, file *gore.GoFile, useComment bool) {
    227 358   fn, err := r2.GetCurrentFunction()
    228 359   if err != nil {
    229 360   fmt.Printf("Failed to get current function: %s.\n", err)
    skipped 20 lines
    250 381   
    251 382   // Add line as multiline comment.
    252 383   comment := fmt.Sprintf("%s:%d", fileStr, line)
    253  - encodedComment := base64.StdEncoding.EncodeToString([]byte(comment))
     384 + 
     385 + var cmd string
     386 + if useComment {
     387 + encodedComment := base64.StdEncoding.EncodeToString([]byte(comment))
     388 + cmd = fmt.Sprintf("CCu base64:%s @ 0x%x", encodedComment, pc.Offset)
     389 + } else {
     390 + r2.Run("fs line")
     391 + cmd = fmt.Sprintf("f %s 1 @ 0x%x", cleanupName(comment), pc.Offset)
     392 + }
    254 393   
    255 394   // Execute command.
    256  - cmd := fmt.Sprintf("CCu base64:%s @ 0x%x", encodedComment, pc.Offset)
    257 395   _, err := r2.Run(cmd)
    258 396   if err != nil {
    259 397   fmt.Println("Error when adding comment:", err)
    260 398   return
    261 399   }
     400 + }
     401 + if !useComment {
     402 + r2.Run("fs *")
    262 403   }
    263 404  }
    264 405   
  • ■ ■ ■ ■ ■ ■
    src.go
     1 +// Copyright 2019-2021 The GoRE Authors. All rights reserved.
     2 +// Use of this source code is governed by the license that
     3 +// can be found in the LICENSE file.
     4 + 
     5 +package main
     6 + 
     7 +import (
     8 + "fmt"
     9 + "os"
     10 + "path/filepath"
     11 + 
     12 + "github.com/goretk/gore"
     13 + "github.com/spf13/cobra"
     14 +)
     15 + 
     16 +func init() {
     17 + // Flags
     18 + var includeSTD bool
     19 + var includeVendor bool
     20 + var includeUnknown bool
     21 + var includedList []string
     22 + 
     23 + pkgSrc := &cobra.Command{
     24 + Use: "source path/to/go/file",
     25 + Aliases: []string{"src", "s"},
     26 + Short: "Source Code Projection.",
     27 + Long: longSrcHelp,
     28 + Args: cobra.ExactArgs(1),
     29 + Run: func(cmd *cobra.Command, args []string) {
     30 + listSrc(args[0], listSrcOptions{
     31 + std: includeSTD,
     32 + vend: includeVendor,
     33 + unk: includeUnknown,
     34 + include: includedList,
     35 + })
     36 + },
     37 + }
     38 + 
     39 + pkgSrc.Flags().BoolVarP(&includeSTD, "std", "s", false, "Include standard library packages.")
     40 + pkgSrc.Flags().BoolVarP(&includeVendor, "vendor", "v", false, "Include 3rd party/vendor packages.")
     41 + pkgSrc.Flags().BoolVarP(&includeUnknown, "unknown", "u", false, "Include unidentified packages.")
     42 + pkgSrc.Flags().StringSliceVarP(&includedList, "include", "i", nil, "Include the following packages. Can be provided as a comma-separated list or via providing the flag multiple times.")
     43 + 
     44 + rootCmd.AddCommand(pkgSrc)
     45 +}
     46 + 
     47 +type listSrcOptions struct {
     48 + std bool
     49 + vend bool
     50 + unk bool
     51 + include []string
     52 +}
     53 + 
     54 +func listSrc(fileStr string, opts listSrcOptions) {
     55 + fp, err := filepath.Abs(fileStr)
     56 + if err != nil {
     57 + fmt.Fprintf(os.Stderr, "Failed to parse the filepath: %s.\n", err)
     58 + os.Exit(1)
     59 + }
     60 + 
     61 + f, err := gore.Open(fp)
     62 + if err != nil {
     63 + fmt.Fprintf(os.Stderr, "Error when opening the file: %s.\n", err)
     64 + os.Exit(1)
     65 + }
     66 + defer f.Close()
     67 + 
     68 + packages, err := f.GetPackages()
     69 + if err != nil {
     70 + fmt.Fprintf(os.Stderr, "Error when parsing packages: %s.\n", err)
     71 + os.Exit(1)
     72 + }
     73 + 
     74 + // Err check not needed since the parsing was has already been checked.
     75 + vn, _ := f.GetVendors()
     76 + if opts.vend {
     77 + packages = append(packages, vn...)
     78 + } else {
     79 + for _, i := range opts.include {
     80 + for _, v := range vn {
     81 + if v.Name == i {
     82 + packages = append(packages, v)
     83 + }
     84 + }
     85 + }
     86 + }
     87 + 
     88 + std, _ := f.GetSTDLib()
     89 + if opts.std {
     90 + packages = append(packages, std...)
     91 + } else {
     92 + for _, i := range opts.include {
     93 + for _, v := range std {
     94 + if v.Name == i {
     95 + packages = append(packages, v)
     96 + }
     97 + }
     98 + }
     99 + }
     100 + 
     101 + unk, _ := f.GetUnknown()
     102 + if opts.unk {
     103 + packages = append(packages, unk...)
     104 + } else {
     105 + for _, i := range opts.include {
     106 + for _, v := range unk {
     107 + if v.Name == i {
     108 + packages = append(packages, v)
     109 + }
     110 + }
     111 + }
     112 + }
     113 + 
     114 + printFolderStructures(f, packages)
     115 +}
     116 + 
     117 +func printFolderStructures(f *gore.GoFile, pkgs []*gore.Package) {
     118 + for i, p := range pkgs {
     119 + if i != 0 {
     120 + fmt.Printf("\n")
     121 + }
     122 + fmt.Printf("Package %s: %s\n", p.Name, p.Filepath)
     123 + for _, sf := range f.GetSourceFiles(p) {
     124 + sf.Postfix = "\t"
     125 + fmt.Printf("%s\n", sf)
     126 + }
     127 + }
     128 +}
     129 + 
     130 +const longSrcHelp = `Source Code Projection
     131 + 
     132 +Construct a source code tree layout based on the metadata found in the binary.
     133 +The output includes the package name and its folder location at compile time.
     134 +For each file, the functions defined within are printed. The output also
     135 +includes auto generated functions produced by the compiler. For each function,
     136 +redress tries to guess the starting and ending line number.
     137 + Folder -> File -> Function -> Line
     138 + 
     139 +By default, standard library and 3rd party packages are excluded but can be
     140 +included by providing the flags "std", "vendor", and/or "unknown". It is also
     141 +possible to include individual packages with the "include" flag.
     142 +`
     143 + 
  • ■ ■ ■ ■ ■ ■
    standalone.go
    1  -// Copyright 2019 The GoRE.tk Authors. All rights reserved.
    2  -// Use of this source code is governed by the license that
    3  -// can be found in the LICENSE file.
    4  - 
    5  -package main
    6  - 
    7  -import (
    8  - "flag"
    9  - "fmt"
    10  - "log"
    11  - "path/filepath"
    12  - "reflect"
    13  - "sort"
    14  - "strings"
    15  - 
    16  - "github.com/goretk/gore"
    17  -)
    18  - 
    19  -func standalone() {
    20  - if len(flag.Args()) != 1 {
    21  - return
    22  - }
    23  - 
    24  - fileStr, err := filepath.Abs(flag.Arg(0))
    25  - if err != nil {
    26  - log.Fatalln("Failed to parse the filepath:", err)
    27  - }
    28  - 
    29  - f, err := gore.Open(fileStr)
    30  - if err != nil {
    31  - log.Fatalln("Error when opening the file:", err)
    32  - }
    33  - defer f.Close()
    34  - 
    35  - // Setting forced version if given
    36  - if *options.forceVersion != "" {
    37  - if err = f.SetGoVersion(*options.forceVersion); err != nil {
    38  - fmt.Println("Failed to set the given Go version:", err)
    39  - return
    40  - }
    41  - }
    42  - 
    43  - if *options.printCompiler {
    44  - cmp, err := f.GetCompilerVersion()
    45  - if err != nil {
    46  - fmt.Println("Error when extracting compiler information:", err)
    47  - } else {
    48  - fmt.Printf("Compiler version: %s (%s)\n", cmp.Name, cmp.Timestamp)
    49  - }
    50  - }
    51  - 
    52  - pkgs, err := f.GetPackages()
    53  - if err != nil {
    54  - fmt.Println(err)
    55  - return
    56  - }
    57  - 
    58  - if *options.printTypes || *options.printStructs || *options.printIntefaces {
    59  - typs, err := f.GetTypes()
    60  - if err == gore.ErrNoGoVersionFound {
    61  - // Force the assumed version and try again.
    62  - f.SetGoVersion(assumedGoVersion)
    63  - typs, err = f.GetTypes()
    64  - }
    65  - if err != nil {
    66  - fmt.Println(err)
    67  - return
    68  - }
    69  - printTypes(typs, &options)
    70  - }
    71  - 
    72  - if *options.printPackages {
    73  - pkgs, err := f.GetPackages()
    74  - if err != nil {
    75  - fmt.Println(err)
    76  - return
    77  - }
    78  - printPackages("Packages", pkgs)
    79  - if *options.printVendorPackages {
    80  - vendorpkgs, err := f.GetVendors()
    81  - if err != nil {
    82  - fmt.Println(err)
    83  - return
    84  - }
    85  - printPackages("Vendors", vendorpkgs)
    86  - }
    87  - if *options.printStdLibPackages {
    88  - stdpkgs, err := f.GetSTDLib()
    89  - if err != nil {
    90  - fmt.Println(err)
    91  - return
    92  - }
    93  - printPackages("Standard Libraries", stdpkgs)
    94  - }
    95  - if *options.printUnknownPackages {
    96  - unknownpkgs, err := f.GetUnknown()
    97  - if err != nil {
    98  - fmt.Println(err)
    99  - return
    100  - }
    101  - printPackages("Unknown Libraries", unknownpkgs)
    102  - }
    103  - }
    104  - 
    105  - if *options.printUnknownPackages {
    106  - upkg, _ := f.GetUnknown()
    107  - pkgs = append(pkgs, upkg...)
    108  - }
    109  - 
    110  - if *options.printVendorPackages {
    111  - vpkg, _ := f.GetVendors()
    112  - pkgs = append(pkgs, vpkg...)
    113  - }
    114  - 
    115  - if *options.printStdLibPackages {
    116  - std, _ := f.GetSTDLib()
    117  - pkgs = append(pkgs, std...)
    118  - }
    119  - 
    120  - if *options.printSourceTree {
    121  - printFolderStructures(pkgs)
    122  - }
    123  -}
    124  - 
    125  -func printPackages(header string, pkgs []*gore.Package) {
    126  - fmt.Printf("%s:\n", header)
    127  - sort.Slice(pkgs, func(i, j int) bool {
    128  - return pkgs[i].Name < pkgs[j].Name
    129  - })
    130  - for _, p := range pkgs {
    131  - if *options.includeFilepath {
    132  - fmt.Printf("%s | %s\n", p.Name, p.Filepath)
    133  - } else {
    134  - fmt.Printf("%s\n", p.Name)
    135  - }
    136  - }
    137  - fmt.Println("")
    138  -}
    139  - 
    140  -func printFolderStructures(pkgs []*gore.Package) {
    141  - for _, p := range pkgs {
    142  - fmt.Printf("Package %s: %s\n", p.Name, p.Filepath)
    143  - for _, sf := range p.GetSourceFiles() {
    144  - sf.Postfix = "\t"
    145  - fmt.Printf("%s\n", sf)
    146  - }
    147  - }
    148  -}
    149  - 
    150  -func printTypes(typs []*gore.GoType, opts *option) {
    151  - if *opts.printTypes {
    152  - *opts.printStructs = true
    153  - *opts.printIntefaces = true
    154  - }
    155  - for _, typ := range typs {
    156  - // Try to filter out vendor packages if needed.
    157  - if !*opts.printVendorPackages && strings.Contains(typ.PackagePath, "/vendor/") {
    158  - continue
    159  - }
    160  - 
    161  - // Try to filter out std packages if needed.
    162  - if !*opts.printStdLibPackages &&
    163  - (gore.IsStandardLibrary(typ.PackagePath) ||
    164  - strings.HasPrefix(typ.Name, "map.") ||
    165  - strings.HasPrefix(typ.Name, "*map.")) {
    166  - continue
    167  - }
    168  - 
    169  - if (*opts.printStructs) && (typ.Kind == reflect.Struct) {
    170  - fmt.Println(gore.StructDef(typ))
    171  - if *options.printMethods && len(typ.Methods) > 0 {
    172  - fmt.Println(gore.MethodDef(typ) + "\n")
    173  - } else {
    174  - fmt.Println("")
    175  - }
    176  - continue
    177  - }
    178  - if (*opts.printIntefaces) && (typ.Kind == reflect.Interface) {
    179  - fmt.Println(gore.InterfaceDef(typ) + "\n")
    180  - continue
    181  - }
    182  - if *opts.printTypes {
    183  - fmt.Println(typ)
    184  - if *options.printMethods && len(typ.Methods) > 0 {
    185  - fmt.Println(gore.MethodDef(typ) + "\n")
    186  - } else {
    187  - fmt.Println("")
    188  - }
    189  - }
    190  - }
    191  -}
    192  - 
  • ■ ■ ■ ■ ■ ■
    type.go
     1 +// Copyright 2021 The GoRE Authors. All rights reserved.
     2 +// Use of this source code is governed by the license that
     3 +// can be found in the LICENSE file.
     4 +package main
     5 + 
     6 +import (
     7 + "bytes"
     8 + "fmt"
     9 + "go/format"
     10 + "os"
     11 + "path/filepath"
     12 + "reflect"
     13 + "strings"
     14 + 
     15 + gore "github.com/goretk/gore"
     16 + "github.com/spf13/cobra"
     17 +)
     18 + 
     19 +func init() {
     20 + // Flags
     21 + var includeStd bool
     22 + var includeVendor bool
     23 + var includeMethods bool
     24 + var forceGoVersion string
     25 + 
     26 + typCmd := &cobra.Command{
     27 + Use: "types {struct|interface|all} path/to/go/file",
     28 + Aliases: []string{"type", "typ", "t"},
     29 + Short: "List types.",
     30 + Long: longTypesHelp,
     31 + Args: cobra.ExactArgs(2),
     32 + ValidArgs: []string{"struct", "interface", "all"},
     33 + Run: func(cmd *cobra.Command, args []string) {
     34 + // Find what types should be printed
     35 + opt := listTypesOptions{}
     36 + fpArg := 0
     37 + for i, a := range args {
     38 + switch a {
     39 + case "struct":
     40 + opt.structs = true
     41 + case "interface":
     42 + opt.interfaces = true
     43 + case "all":
     44 + opt.all = true
     45 + default:
     46 + fpArg = i
     47 + }
     48 + }
     49 + 
     50 + // Check mode.
     51 + num := 0
     52 + if opt.all {
     53 + num++
     54 + }
     55 + if opt.interfaces {
     56 + num++
     57 + }
     58 + if opt.structs {
     59 + num++
     60 + }
     61 + 
     62 + if num > 1 {
     63 + fmt.Fprintf(os.Stderr, "struct, interface and all are mutually exclusive. Only one can be used at the time.\n")
     64 + os.Exit(1)
     65 + } else if num == 0 {
     66 + fmt.Fprintf(os.Stderr, "One of: struct, interface or all needs to be used.\n")
     67 + os.Exit(1)
     68 + }
     69 + 
     70 + opt.std = includeStd
     71 + opt.vendor = includeVendor
     72 + opt.methods = includeMethods
     73 + opt.goversion = forceGoVersion
     74 + 
     75 + listTypes(args[fpArg], opt)
     76 + },
     77 + }
     78 + 
     79 + typCmd.Flags().BoolVarP(&includeStd, "std", "s", false, "Include standard library packages.")
     80 + typCmd.Flags().BoolVarP(&includeVendor, "vendor", "v", false, "Include 3rd party/vendor packages.")
     81 + typCmd.Flags().BoolVarP(&includeMethods, "methods", "m", false, "Include method definitions.")
     82 + typCmd.Flags().StringVar(&forceGoVersion, "version", assumedGoVersion, "Fallback compiler version.")
     83 + 
     84 + rootCmd.AddCommand(typCmd)
     85 +}
     86 + 
     87 +type listTypesOptions struct {
     88 + structs bool
     89 + interfaces bool
     90 + all bool
     91 + std bool
     92 + vendor bool
     93 + methods bool
     94 + goversion string
     95 +}
     96 + 
     97 +func listTypes(fileStr string, opts listTypesOptions) {
     98 + fp, err := filepath.Abs(fileStr)
     99 + if err != nil {
     100 + fmt.Fprintf(os.Stderr, "Failed to parse the filepath: %s.\n", err)
     101 + os.Exit(1)
     102 + }
     103 + 
     104 + f, err := gore.Open(fp)
     105 + if err != nil {
     106 + fmt.Fprintf(os.Stderr, "Error when opening the file: %s.\n", err)
     107 + os.Exit(1)
     108 + }
     109 + defer f.Close()
     110 + 
     111 + typs, err := f.GetTypes()
     112 + if err == gore.ErrNoGoVersionFound {
     113 + // Force the assumed version and try again.
     114 + f.SetGoVersion(opts.goversion)
     115 + typs, err = f.GetTypes()
     116 + }
     117 + if err != nil {
     118 + fmt.Fprintf(os.Stderr, "Error when enumerating types: %s.\n", err)
     119 + os.Exit(1)
     120 + }
     121 + 
     122 + printTypes(typs, opts)
     123 +}
     124 + 
     125 +func printTypes(typs []*gore.GoType, opts listTypesOptions) {
     126 + if opts.all {
     127 + opts.structs = true
     128 + opts.interfaces = true
     129 + }
     130 + 
     131 + buf := &bytes.Buffer{}
     132 + 
     133 + for _, typ := range typs {
     134 + // Try to filter out vendor packages if needed.
     135 + if !opts.vendor && strings.Contains(typ.PackagePath, "/vendor/") {
     136 + continue
     137 + }
     138 + 
     139 + // Try to filter out std packages if needed.
     140 + if !opts.std &&
     141 + (gore.IsStandardLibrary(typ.PackagePath) ||
     142 + strings.HasPrefix(typ.Name, "map.") ||
     143 + strings.HasPrefix(typ.Name, "*map.")) {
     144 + continue
     145 + }
     146 + 
     147 + if (opts.structs) && (typ.Kind == reflect.Struct) {
     148 + s := gore.StructDef(typ)
     149 + out, err := format.Source([]byte(strings.ReplaceAll(s, ".", "____")))
     150 + if err != nil {
     151 + fmt.Fprintf(buf, "%s\n", s)
     152 + } else {
     153 + fmt.Fprintf(buf, "%s\n", strings.ReplaceAll(string(out), "____", "."))
     154 + }
     155 + if opts.methods && len(typ.Methods) > 0 {
     156 + fmt.Fprintf(buf, "%s\n\n", gore.MethodDef(typ))
     157 + } else {
     158 + fmt.Fprintf(buf, "\n")
     159 + }
     160 + continue
     161 + }
     162 + if (opts.interfaces) && (typ.Kind == reflect.Interface) {
     163 + i := gore.InterfaceDef(typ)
     164 + out, err := format.Source([]byte(strings.ReplaceAll(i, ".", "____")))
     165 + if err != nil {
     166 + fmt.Fprintf(buf, "%s\n", i)
     167 + } else {
     168 + fmt.Fprintf(buf, "%s\n", strings.ReplaceAll(string(out), "____", "."))
     169 + }
     170 + continue
     171 + }
     172 + if opts.all {
     173 + fmt.Fprintf(buf, "%s\n", typ)
     174 + if opts.methods && len(typ.Methods) > 0 {
     175 + fmt.Fprintf(buf, "%s\n\n", gore.MethodDef(typ))
     176 + } else {
     177 + fmt.Fprintf(buf, "\n")
     178 + }
     179 + }
     180 + }
     181 + 
     182 + fmt.Println(buf.String())
     183 +}
     184 + 
     185 +const longTypesHelp = `List Types
     186 + 
     187 +Redress can display different type data found in the binary. Interfaces can be
     188 +extracted with the "interface" argument while structures can be extracted with
     189 +the "struct" argument.
     190 + 
     191 +By default, standard library types are filtered out. These can be included
     192 +by also providing the standard library flag.
     193 + 
     194 +Method definitions for types can be included by using the method flag.
     195 + 
     196 +It is also possible to print all types in the binary by using the "all"
     197 +argument.
     198 + 
     199 +Redress tries to detect the version of the compiler that produced the binary.
     200 +If this process fails, a fallback version can be provided.
     201 +`
     202 + 
Please wait...
Page is in error, reload to recover