mirror of
https://github.com/BishopFox/sliver.git
synced 2026-11-08 08:04:14 -10:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1af9071e4d | ||
|
|
be62e6f9e6 |
No files matched your search
@@ -28,9 +28,15 @@ import (
|
||||
|
||||
var extensions map[string]Extension
|
||||
|
||||
type Callbacks struct {
|
||||
SendData func([]byte)
|
||||
OnFinish func([]byte)
|
||||
SendError func([]byte)
|
||||
}
|
||||
|
||||
type Extension interface {
|
||||
Load() error
|
||||
Call(exportName string, arguments []byte, callback func([]byte)) error
|
||||
Call(exportName string, arguments []byte, callbacks Callbacks) error
|
||||
GetID() string
|
||||
GetArch() string
|
||||
}
|
||||
@@ -47,9 +53,9 @@ func List() []string {
|
||||
return extList
|
||||
}
|
||||
|
||||
func Run(extID string, funcName string, arguments []byte, callback func([]byte)) error {
|
||||
func Run(extID string, funcName string, arguments []byte, callbacks Callbacks) error {
|
||||
if ext, found := extensions[extID]; found {
|
||||
return ext.Call(funcName, arguments, callback)
|
||||
return ext.Call(funcName, arguments, callbacks)
|
||||
}
|
||||
// {{if .Config.Debug}}
|
||||
for id, ext := range extensions {
|
||||
|
||||
@@ -85,7 +85,7 @@ func (d *DarwinExtension) Load() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DarwinExtension) Call(export string, arguments []byte, onFinish func([]byte)) error {
|
||||
func (d *DarwinExtension) Call(export string, arguments []byte, callbacks Callbacks) error {
|
||||
// We currently have 2 issues with Darwin extensions:
|
||||
// - cppgo (used by universal) fucks up when calling a function with more than 1 argument
|
||||
// - we don't have Go callback support for the loaded extension,
|
||||
@@ -124,7 +124,7 @@ func (d *DarwinExtension) Call(export string, arguments []byte, onFinish func([]
|
||||
// We currently don't have a way to trigger a callback
|
||||
// in the loaded code for Darwin.
|
||||
if outData.Len() > 0 {
|
||||
onFinish(outData.Bytes())
|
||||
callbacks.OnFinish(outData.Bytes())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -36,6 +36,12 @@ const (
|
||||
Failure = 1
|
||||
)
|
||||
|
||||
type CallbacksPtr struct {
|
||||
sendData uintptr
|
||||
onFinish uintptr
|
||||
sendError uintptr
|
||||
}
|
||||
|
||||
type WindowsExtension struct {
|
||||
id string
|
||||
data []byte
|
||||
@@ -92,15 +98,21 @@ func (w *WindowsExtension) Load() error {
|
||||
}
|
||||
|
||||
// Call - Call an extension export
|
||||
func (w *WindowsExtension) Call(export string, arguments []byte, onFinish func([]byte)) error {
|
||||
func (w *WindowsExtension) Call(export string, arguments []byte, callbacks Callbacks) error {
|
||||
var (
|
||||
argumentsPtr uintptr
|
||||
argumentsSize uintptr
|
||||
argumentsPtr uintptr
|
||||
argumentsSize uintptr
|
||||
callbacksPtr CallbacksPtr
|
||||
callbacksStructPtr uintptr
|
||||
)
|
||||
if w.module == nil {
|
||||
return errors.New("{{if .Config.Debug}} module not loaded {{end}}")
|
||||
}
|
||||
callback := syscall.NewCallback(newWindowsExtensionCallback(onFinish))
|
||||
callbacksPtr.onFinish = syscall.NewCallback(newWindowsExtensionCallback(callbacks.OnFinish))
|
||||
callbacksPtr.sendData = syscall.NewCallback(newWindowsExtensionCallback(callbacks.SendData))
|
||||
callbacksPtr.sendError = syscall.NewCallback(newWindowsExtensionCallback(callbacks.SendError))
|
||||
callbacksStructPtr = uintptr(unsafe.Pointer(&callbacks))
|
||||
|
||||
exportPtr, err := w.module.ProcAddressByName(export)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -117,7 +129,7 @@ func (w *WindowsExtension) Call(export string, arguments []byte, onFinish func([
|
||||
// where goCallback = int(char *, int)
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
_, _, errNo := syscall.Syscall(exportPtr, 3, argumentsPtr, argumentsSize, callback)
|
||||
_, _, errNo := syscall.Syscall(exportPtr, 3, argumentsPtr, argumentsSize, callbacksStructPtr)
|
||||
if errNo != 0 {
|
||||
return errors.New(errNo.Error())
|
||||
}
|
||||
|
||||
@@ -122,11 +122,32 @@ func callExtensionHandler(data []byte, resp RPCResponse) {
|
||||
Response: &commonpb.Response{},
|
||||
}
|
||||
gotOutput := false
|
||||
err = extension.Run(callReq.Name, callReq.Export, callReq.Args, func(out []byte) {
|
||||
|
||||
onFinish := func(out []byte) {
|
||||
gotOutput = true
|
||||
callResp.Output = out
|
||||
data, err = proto.Marshal(callResp)
|
||||
resp(data, err)
|
||||
}
|
||||
|
||||
sendData := func(out []byte) {
|
||||
gotOutput = true
|
||||
callResp.Output = out
|
||||
data, err = proto.Marshal(callResp)
|
||||
resp(data, err)
|
||||
}
|
||||
|
||||
sendError := func(out []byte) {
|
||||
gotOutput = true
|
||||
callResp.Output = out
|
||||
data, err = proto.Marshal(callResp)
|
||||
resp(data, err)
|
||||
}
|
||||
|
||||
err = extension.Run(callReq.Name, callReq.Export, callReq.Args, extension.Callbacks{
|
||||
OnFinish: onFinish,
|
||||
SendData: sendData,
|
||||
SendError: sendError,
|
||||
})
|
||||
// Only send back synchronously if there was an error
|
||||
if err != nil || !gotOutput {
|
||||
|
||||
@@ -924,11 +924,31 @@ func callExtensionHandler(data []byte, resp RPCResponse) {
|
||||
|
||||
callResp := &sliverpb.CallExtension{Response: &commonpb.Response{}}
|
||||
gotOutput := false
|
||||
err = extension.Run(callReq.Name, callReq.Export, callReq.Args, func(out []byte) {
|
||||
var onFinish = func(out []byte) {
|
||||
gotOutput = true
|
||||
callResp.Output = out
|
||||
data, err = proto.Marshal(callResp)
|
||||
resp(data, err)
|
||||
}
|
||||
|
||||
var sendData = func(out []byte) {
|
||||
gotOutput = true
|
||||
callResp.Output = out
|
||||
data, err = proto.Marshal(callResp)
|
||||
resp(data, err)
|
||||
}
|
||||
|
||||
var sendError = func(out []byte) {
|
||||
gotOutput = true
|
||||
callResp.Output = out
|
||||
data, err = proto.Marshal(callResp)
|
||||
resp(data, err)
|
||||
}
|
||||
|
||||
err = extension.Run(callReq.Name, callReq.Export, callReq.Args, extension.Callbacks{
|
||||
OnFinish: onFinish,
|
||||
SendData: sendData,
|
||||
SendError: sendError,
|
||||
})
|
||||
// Only send back synchronously if there was an error
|
||||
if err != nil || !gotOutput {
|
||||
|
||||
Reference in new issue
Block a user