Documentation ¶
Index ¶
- Constants
- Variables
- func InitializeHook(streamID uint32, cfg AdapterConfig) (net.Conn, error)
- type Adapter
- type AdapterConfig
- type DLLAlreadyInjectedError
- type Decoder
- type Envelope
- type FrameReader
- type HookDataSender
- type Manager
- type RemoteProcessProvider
- type Stream
- type StreamPinger
- type StreamReader
- type StreamSender
Constants ¶
const ( OpDebug = iota OpPing OpExit OpRecv OpSend )
Constants for the ops field in an Envelope
Variables ¶
var ErrInvalidLength = errors.New("Invalid length encountered in byte stream")
ErrInvalidLength is returned whenever data is corrupted in the byte stream and we have potentially faulty data.
Functions ¶
func InitializeHook ¶
func InitializeHook(streamID uint32, cfg AdapterConfig) (net.Conn, error)
InitializeHook injects the specified DLL into the target process and attempts to initialize a connection with this hook. It returns the connection if successful, and it returns an error if initialization fails.
Types ¶
type Adapter ¶
type Adapter struct {
*suture.Supervisor
}
Adapter defines the implementation of the hook Adapter
func NewAdapter ¶
func NewAdapter(cfg AdapterConfig, logger *zap.Logger) *Adapter
NewAdapter creates a new instance of the hook Adapter
type AdapterConfig ¶
type AdapterConfig struct { HookConfig config.HookConfig StreamUp chan<- stream.Provider StreamDown chan<- int RemoteProcessProvider RemoteProcessProvider ProcessEnumerator process.Enumerator }
AdapterConfig provides commonly accessed configuration for the hook to the services that make up the hook Adapter
type DLLAlreadyInjectedError ¶
type DLLAlreadyInjectedError interface {
IsDLLAlreadyInjectedError()
}
DLLAlreadyInjectedError is an error that indicates the DLL has already been injected.
type Decoder ¶
type Decoder struct {
// contains filtered or unexported fields
}
Decoder is responsible for reading bytes from the provided reader and decoding the data into envelopes
func NewDecoder ¶
NewDecoder creates a new decoder instance given an io.Reader and a buffer size. Data read from the Reader will be buffered to store partial data as it comes in.
func (*Decoder) NextEnvelope ¶
NextEnvelope consumes an some amount of data on the Reader and returns the next full Envelope. Since the Envelope isn't by itself a robust format of data transmission, the decoder might or might not recover from decoding faulty data. Since the intended io.Reader is a named pipe connection, the chance of a failure happening is really low.
If the length is at least readable, but it's too small, it will discard the faulty data and continue attempting to read Envelopes. However, there is no recovery path if the data is corrupted in other ways, and subsequent calls to NextEnvelope will return the same thing.
type Envelope ¶
Envelope defines the message format used to communicate with the hook Length is the length of the entire envelope, including the length field. The size of the Envelope is 9 bytes + len(Additional).
func DecodeEnvelope ¶
DecodeEnvelope transforms byte data to an Envelope
type FrameReader ¶
type FrameReader struct {
// contains filtered or unexported fields
}
FrameReader reads in envelopes from the hook, parses them, and converts the data into xivnet.Frames
func NewFrameReader ¶
func NewFrameReader( streamID uint32, envelopesChan <-chan Envelope, frameDecoderFactory message.DecoderFactory, logger *zap.Logger, ) *FrameReader
NewFrameReader creates a new FrameReader provided a data source and a factory to create a new frame decoder
func (*FrameReader) Serve ¶
func (d *FrameReader) Serve()
Serve runs the frame reader. It is responsible for sorting incoming envelopes of data to the correct decoder and forwarding all the decoded frames to subscribers.
func (*FrameReader) Stop ¶
func (d *FrameReader) Stop()
Stop will shutdown this service and wait on it to stop before returning.
func (*FrameReader) SubscribeEgress ¶
func (d *FrameReader) SubscribeEgress() <-chan *xivnet.Frame
SubscribeIngress provides a channel on which consumers can listen for processed egress frames decoded from the envelopes.
func (*FrameReader) SubscribeIngress ¶
func (d *FrameReader) SubscribeIngress() <-chan *xivnet.Frame
SubscribeIngress provides a channel on which consumers can listen for processed ingress frames decoded from the envelopes.
type HookDataSender ¶
HookDataSender defines the interface that allows the sending of data to the hook connection from the adapter.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager is responsible for starting up new hook streams whenever it detects that a new instance of a watched process is created. It is also responsible for shutting down those streams when a watched process is closed. Additionally, the Manager notifies the StreamUp and StreamDown channels when the watched process is created and closed, respectively.
func NewManager ¶
func NewManager( cfg AdapterConfig, addProcEventChan <-chan uint32, remProcEventChan <-chan uint32, streamBuilder func(streamID uint32) Stream, streamSupervisor *suture.Supervisor, logger *zap.Logger, ) *Manager
NewManager creates a new hook Stream Manager
type RemoteProcessProvider ¶
type RemoteProcessProvider interface { InjectDLL(processID uint32, payloadPath string) error DialPipe(path string, timeout *time.Duration) (net.Conn, error) IsPipeClosed(err error) bool }
RemoteProcessProvider defines the interface that exposes methods for interacting with other processes on the system
type Stream ¶
Stream provides the interface for a long running process responsible for handling data coming from the hook, as well as sending data to the hook when necessary.
type StreamPinger ¶
type StreamPinger struct {
// contains filtered or unexported fields
}
StreamPinger sends a ping through the hook connection to make sure it's still alive
func NewStreamPinger ¶
func NewStreamPinger(hds HookDataSender, pingInterval time.Duration, logger *zap.Logger) *StreamPinger
NewStreamPinger returns a new StreamPinger
func (*StreamPinger) Serve ¶
func (p *StreamPinger) Serve()
Serve runs the service responsible for the periodic pinging of the hook connection.
func (*StreamPinger) Stop ¶
func (p *StreamPinger) Stop()
Stop will shutdown this service and wait on it to stop before returning.
type StreamReader ¶
type StreamReader struct {
// contains filtered or unexported fields
}
StreamReader reads data from the hook connection and decodes it into envelopes
func NewStreamReader ¶
func NewStreamReader(hookConn io.ReadCloser, logger *zap.Logger) *StreamReader
NewStreamReader creates a new StreamReader
func (*StreamReader) Complete ¶
func (r *StreamReader) Complete() bool
Complete lets the supervisor know it's okay for this process to shut down on its own (if the pipe connection shuts down).
func (*StreamReader) ReceivedEnvelopesListener ¶
func (r *StreamReader) ReceivedEnvelopesListener() <-chan Envelope
ReceivedEnvelopesListener returns a channel on which consumers can listen for envelopes from the hook connection.
func (*StreamReader) Serve ¶
func (r *StreamReader) Serve()
Serve runs the service responsible for reading data from the hook connection and decoding the data as envelopes.
func (*StreamReader) Stop ¶
func (r *StreamReader) Stop()
Stop will shutdown this service and wait on it to stop before returning.
type StreamSender ¶
type StreamSender struct {
// contains filtered or unexported fields
}
StreamSender listens for requests and sends data to the hook.
func NewStreamSender ¶
func NewStreamSender(hookConn io.WriteCloser, logger *zap.Logger) *StreamSender
NewStreamSender creates a new StreamSender
func (*StreamSender) Send ¶
func (s *StreamSender) Send(op byte, data uint32, additional []byte)
Send queues a request to send the data as an Envelope through the hook connection.
func (*StreamSender) Serve ¶
func (s *StreamSender) Serve()
Serve runs the service responsible for handling requests to send data to the hook connection.
func (*StreamSender) Stop ¶
func (s *StreamSender) Stop()
Stop will shutdown this service and wait on it to stop before returning.