-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
tzerk
authored and
tzerk
committed
Feb 28, 2017
1 parent
622c246
commit 870c83b
Showing
6 changed files
with
292 additions
and
254 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package lib | ||
|
||
import ( | ||
"github.com/mitchellh/go-ps" | ||
"log" | ||
"os" | ||
) | ||
|
||
func killCoherentUI() { | ||
// Find process(es) | ||
chp, err := ps.Processes() | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
// Find PID and kill | ||
for _, v := range chp { | ||
if v.Executable() == "CoherentUI_Host.exe" { | ||
proc, err := os.FindProcess(v.Pid()) | ||
|
||
if err != nil { | ||
log.Println(err) | ||
} | ||
|
||
defer func() { | ||
recover() // 1 | ||
return | ||
}() | ||
// Kill the process | ||
proc.Kill() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package lib | ||
|
||
import ( | ||
"strings" | ||
"io/ioutil" | ||
"os" | ||
"gopkg.in/yaml.v2" | ||
) | ||
|
||
// Telegram and program settings (config.yml) | ||
// Guide: http://sweetohm.net/article/go-yaml-parsers.en.html | ||
type Config struct { | ||
Token string | ||
Botid string | ||
Chatid string | ||
Message string | ||
StayAlive bool | ||
Process string | ||
TimeBetweenChecksInS int | ||
KillOnDC bool | ||
ShutdownOnDC bool | ||
KillCoherentUI bool | ||
} | ||
|
||
func Read_Settings(ex string, err error) Config { | ||
|
||
//// SETTINGS | ||
//-------------------------------------------------------------------------------------------------------------- | ||
// YAML PARSING | ||
newex := strings.Replace(ex, "BDO-Watchdog.exe", "config.yml", -1) | ||
// This is necessary for dynamic builds in Jetbrains Gogland IDE | ||
//newex = strings.Replace(ex, "Application.exe", "config.yml", -1) | ||
|
||
var config Config | ||
source, err := ioutil.ReadFile(newex) | ||
|
||
if err != nil { | ||
// in theory, using yml.Marshal() would be more elegant, but we want to preserve the yaml comments | ||
// as well as set some default values/hints | ||
defconf := | ||
"## Get updates here: https://github.com/tzerk/BDO-Watchdog/releases/\r\n" + | ||
"## Telegram Bot Settings\r\n" + | ||
"token: \r\n" + | ||
"botid: \r\n" + | ||
"chatid: \r\n" + | ||
"message: BDO disconnected \r\n" + | ||
"\r\n" + | ||
"## Program Settings\r\n" + | ||
"stayalive: false\r\n" + | ||
"process: BlackDesert64.exe\r\n" + | ||
"timebetweenchecksins: 60\r\n" + | ||
"\r\n" + | ||
"# These settings require the .exe to be run with admin rights! \r\n" + | ||
"killondc: true\r\n" + | ||
"shutdownondc: false\r\n" + | ||
"killcoherentui: false" | ||
ioutil.WriteFile("config.yml", []byte(defconf), os.FileMode(int(0777))) | ||
panic(err) | ||
} | ||
err = yaml.Unmarshal(source, &config) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
return(config) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package lib | ||
|
||
import "net/http" | ||
|
||
// --------------------------------------------------------------------------------------------------------------------- | ||
// Send a telegram message using a query URL | ||
func Send_TelegramMessage(config Config) { | ||
// Learn how to setup a telegram bot: https://core.telegram.org/bots | ||
resp, _ := http.Get("https://api.telegram.org/bot" + config.Botid + | ||
":" + config.Token + | ||
"/sendMessage?chat_id=" + config.Chatid + | ||
"&text=" + config.Message) | ||
defer resp.Body.Close() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package lib | ||
|
||
import ( | ||
"github.com/andlabs/ui" | ||
"strconv" | ||
"time" | ||
) | ||
|
||
// --------------------------------------------------------------------------------------------------------------------- | ||
// A wrapper for time.Sleep() that also updates the UI label and progressbar | ||
func wait(config Config, label_Update *ui.Label, pb *ui.ProgressBar) { | ||
tstep := config.TimeBetweenChecksInS | ||
var pbVal int | ||
|
||
if tstep <= 0 { | ||
tstep = 1 | ||
} // otherwise division by 0 | ||
for i := 0; i <= tstep; i++ { | ||
pbVal = int(100/float32(tstep) * float32(i)) | ||
if pbVal > 100 { | ||
pbVal = 100 | ||
} | ||
pb.SetValue(pbVal) | ||
label_Update.SetText(" Next update in... " + strconv.Itoa(tstep - i) + " s") | ||
time.Sleep(1 * time.Second) | ||
} | ||
pb.SetValue(0) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
package lib | ||
|
||
import ( | ||
"os/exec" | ||
"syscall" | ||
"log" | ||
"regexp" | ||
"strconv" | ||
"github.com/andlabs/ui" | ||
"github.com/mitchellh/go-ps" | ||
"os" | ||
"time" | ||
) | ||
|
||
var STATUS bool = false | ||
var CONNECTION bool = false | ||
var PID int | ||
|
||
//-------------------------------------------------------------------------------------------------------------- | ||
// PROCESS | ||
//-------------------------------------------------------------------------------------------------------------- | ||
func Watchdog( | ||
config Config, | ||
label_Status *ui.Label, | ||
label_PID *ui.Label, | ||
label_Connection *ui.Label, | ||
label_Update *ui.Label, | ||
pb *ui.ProgressBar) { | ||
|
||
// KILL CoherentUI_Host.exe | ||
if config.KillCoherentUI { | ||
killCoherentUI() | ||
} | ||
|
||
// INFINITE MAIN LOOP | ||
for { | ||
label_Update.SetText("") | ||
|
||
//// EXIT CONDITION | ||
//----------------- | ||
// If the process is running, but no longer connected we trigger the following actions | ||
if STATUS && !CONNECTION { | ||
|
||
// Use the Telegram API to send a message | ||
Send_TelegramMessage(config) | ||
|
||
// Optional: shutdown the computer if the monitored process is disconnected | ||
if config.ShutdownOnDC { | ||
exec.Command("cmd", "/C", "shutdown", "/s").Run() | ||
} | ||
|
||
// Optional: kill the monitored process if it is disconnected | ||
// requires elevated rights --> start .exe as administrator | ||
if config.KillOnDC { | ||
|
||
proc, err := os.FindProcess(PID) | ||
|
||
if err != nil { | ||
log.Println(err) | ||
} | ||
|
||
defer func() { | ||
recover() // 1 | ||
return | ||
}() | ||
// Kill the process | ||
proc.Kill() | ||
|
||
time.Sleep(5 * time.Second) | ||
} | ||
|
||
// Optional (YAML file, default: false): keep ts program open even if | ||
// the process is disconnected | ||
if !config.StayAlive { | ||
os.Exit(1) | ||
} | ||
} | ||
|
||
//// PROCESS | ||
//---------- | ||
p, err := ps.Processes() | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
//// PID | ||
//------ | ||
PID = 0 | ||
for _, v := range p { | ||
if v.Executable() == config.Process { | ||
PID = v.Pid() | ||
} | ||
} | ||
if (PID == 0) { | ||
ui.QueueMain(func () { | ||
STATUS = false | ||
label_Status.SetText(" Status: not running") | ||
label_PID.SetText(" PID: -") | ||
label_Connection.SetText(" Connection: -" ) | ||
}) | ||
|
||
wait(config, label_Update, pb) | ||
continue | ||
} else { | ||
|
||
ui.QueueMain(func () { | ||
STATUS = true | ||
label_Status.SetText(" Status: running") | ||
label_PID.SetText(" PID: " + strconv.Itoa(PID)) | ||
}) | ||
} | ||
|
||
//// CONNECTION STATUS | ||
//-------------------- | ||
// NETSTAT | ||
// the syscall.SysProcAttr trick found here: | ||
// https://www.reddit.com/r/golang/comments/2c1g3x/build_golang_app_reverse_shell_to_run_in_windows/ | ||
cmd := exec.Command("cmd.exe", "/C netstat -aon") | ||
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} | ||
out, err := cmd.Output() | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
|
||
// RegEx matching; try to find the PID in the netstat output | ||
re := regexp.MustCompile(strconv.Itoa(PID)) | ||
byteIndex := re.FindIndex([]byte(out)) | ||
|
||
if (len(byteIndex) == 0) { | ||
ui.QueueMain(func () { | ||
CONNECTION = false | ||
label_Connection.SetText(" Connection: Offline" ) | ||
}) | ||
} else { | ||
// Update labels | ||
ui.QueueMain(func () { | ||
CONNECTION = true | ||
label_Connection.SetText(" Connection: online") | ||
}) | ||
} | ||
|
||
// Wait x seconds before next iteration | ||
wait(config, label_Update, pb) | ||
} | ||
} |
Oops, something went wrong.