├── GUI.png ├── LICENSE ├── Makefile ├── README.md ├── csharp_random └── csharp_random.go ├── examine ├── bytes.go └── examine.go ├── go.mod ├── go.sum ├── main.go ├── main.manifest ├── main.syso ├── main_gui.go ├── output ├── 103171375_file-example_PDF_500_kB.pdf ├── 103171406_file-sample_500kB.docx ├── 103171437_file_example_AVI_480_750kB.avi ├── 103171468_file_example_JPG_500kB.jpg ├── 103171500_file_example_MP4_480_1_5MG.mp4 ├── 103171562_file_example_PPT_1MB.ppt ├── 103171640_file_example_XLSX_50.xlsx ├── 103171671_zip_2MB.zip ├── 615750_CyCraft.png └── 615750_test.txt ├── prometheus_decrypt.go ├── sample ├── CyCraft.png.PROM[prometheushelp@mail.ch] ├── README.md ├── file-example_PDF_500_kB.pdf.PROM[prometheushelp@mail.ch] ├── file-sample_500kB.docx.PROM[prometheushelp@mail.ch] ├── file_example_AVI_480_750kB.avi.PROM[prometheushelp@mail.ch] ├── file_example_JPG_500kB.jpg.PROM[prometheushelp@mail.ch] ├── file_example_MP4_480_1_5MG.mp4.PROM[prometheushelp@mail.ch] ├── file_example_PPT_1MB.ppt.PROM[prometheushelp@mail.ch] ├── file_example_XLSX_50.xlsx.PROM[prometheushelp@mail.ch] ├── test.txt.enc └── zip_2MB.zip.PROM[prometheushelp@mail.ch] └── winsup ├── winsup.go └── winunsup.go /GUI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/GUI.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 CyCraft Technology 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | win32: 2 | GOOS=windows GOARCH=386 go build -tags windows -o prometheus_decrypt_32.exe 3 | 4 | win64: 5 | GOOS=windows GOARCH=amd64 go build -tags windows -o prometheus_decrypt_64.exe 6 | 7 | linux: 8 | GOOS=linux GOARCH=amd64 go build 9 | 10 | win32GUI: 11 | set GOARCH=386 12 | go build -tags windows,gui -ldflags="-H windowsgui -w -s" -o prometheus_decrypt_32_GUI.exe 13 | 14 | win64GUI: 15 | set GOARCH=amd64 16 | go build -tags windows,gui -ldflags="-H windowsgui -w -s" -o prometheus_decrypt_64_GUI.exe 17 | 18 | cross_linux: win32 win64 linux 19 | 20 | gui: win32GUI win64GUI 21 | 22 | all: win32 win64 linux win32GUI win64GUI 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 2 | [![made-with-Go](https://img.shields.io/badge/Made%20with-Go-1f425f.svg)](http://golang.org) 3 | 4 | # Prometheus-Decryptor 5 | 6 | Prometheus-Decryptor is an project to decrypt files encrypted by Prometheus ransomware. 7 | 8 | ## Command Arguments 9 | ``` 10 | Usage of ./bin/prometheus_decrypt: 11 | -b string 12 | Custom search with byte value. (i.e. \xde\xad\xbe\xef -> deadbeef) 13 | Please use ?? to match any byte (i.e. de??beef) 14 | -c Use current tickcount. (only support in Windows) 15 | -d int 16 | Decrypt size when guessing. The default size is 100, and you can specify your own size corresponding to your search pattern. 17 | 0 stands for the guessing file size, and -1 stands for the max header size 100 except for Microsoft documents. (default -1) 18 | -e string 19 | Search file extension. 20 | -f int 21 | Found candidate. (default 1) 22 | -i string 23 | Input encrypted file. 24 | -k string 25 | Decrypt with this key. 26 | -m int 27 | Move backward m minutes from the current decrypted seed when guessing the next sample. (default 30) 28 | -o string 29 | Output decrypted file. 30 | -p int 31 | Use n thread. (default 1) 32 | -r Reversed tickcount. 33 | -s string 34 | Custom search with regular expression. 35 | -t int 36 | Start tickcount. 37 | ``` 38 | 39 | ## Usage 40 | ### Guess password 41 | Guess the password of a png image from tickcount 0. 42 | ```bash 43 | ./prometheus_decrypt -i ./sample/CyCraft.png.PROM\[prometheushelp@mail.ch\] -o ./output/CyCraft.png -e png -p 16 44 | ``` 45 | 46 | In this command, there are 4 arguments: 47 | - i: input encrypted file 48 | - o: output file 49 | - e: search file format 50 | - p: thread count 51 | 52 | ### Reversed Tickcount 53 | Guess the password of a png image from tickcount 100000 in reversed order. 54 | ```bash 55 | ./prometheus_decrypt -i ./sample/CyCraft.png.PROM\[prometheushelp@mail.ch\] -o ./output/CyCraft.png -e png -p 16 -t 100000 -r 56 | ``` 57 | 58 | There are 2 additional arguments: 59 | - t: start from 100000 60 | - r: reversed order (100000...0) 61 | 62 | ### Guess from current tickcount (only for Windows) 63 | Guess the password of a png image from the current tickcount in reversed order. This feature is usually used with reversed order. 64 | ```bash 65 | ./prometheus_decrypt -i ./sample/CyCraft.png.PROM\[prometheushelp@mail.ch\] -o ./output/CyCraft.png -e png -p 16 -c -r 66 | ``` 67 | 68 | There is an additional argument: 69 | - c: start from the current tickcount 70 | 71 | ### Decrypt (Encrypt) with a key 72 | Decrypt (Encrypt) a file with a provided key. 73 | ```bash 74 | ./prometheus_decrypt -i ./sample/CyCraft.png.PROM\[prometheushelp@mail.ch\] -o ./output/CyCraft.png -k "+@[%T-mZSh+E[^^i{W:dpwnhdL4= 56 { 94 | locINext = 1 95 | } 96 | 97 | if locINextp >= 56 { 98 | locINextp = 1 99 | } 100 | 101 | retVal = self.seedArray[locINext] - self.seedArray[locINextp]; 102 | 103 | if retVal == math.MaxInt32 { 104 | retVal-- 105 | } 106 | if retVal < 0 { 107 | retVal += math.MaxInt32 108 | } 109 | 110 | self.seedArray[locINext] = retVal 111 | 112 | self.inext = locINext 113 | self.inextp = locINextp 114 | 115 | return retVal; 116 | } 117 | 118 | func (self *CsRandom) Sample() float64 { 119 | return float64(self.internalSample()) / float64(math.MaxInt32); 120 | } 121 | 122 | func (self *CsRandom) Next(minValue int32, maxValue int32) int32 { 123 | return (int32(self.Sample() * float64(maxValue - minValue)) + minValue); 124 | } 125 | -------------------------------------------------------------------------------- /examine/bytes.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 CyCraft Technology 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | package examine 26 | 27 | import( 28 | "bytes" 29 | "strconv" 30 | "log" 31 | ) 32 | 33 | func matchBytes(str []byte, sub string) bool { 34 | if len(str) < len(sub) { 35 | return false 36 | } 37 | 38 | n := len(sub) / 2 39 | i0, err := strconv.ParseUint(sub[0:2], 16, 8) 40 | if err != nil { 41 | log.Fatal(err) 42 | } 43 | c0 := byte(i0) 44 | 45 | for i, t := 0, len(str)-n+1; i < t; i++ { 46 | if str[i] != c0 { 47 | o := bytes.IndexByte(str[i+1:t], c0) 48 | if o < 0 { 49 | return false 50 | } 51 | i += o + 1 52 | } 53 | if equalBytes(str[i:i+n], sub) { 54 | return true 55 | } 56 | } 57 | 58 | return false 59 | } 60 | 61 | func equalBytes(str []byte, sub string) bool { 62 | for i:=0; i deadbeef)\nPlease use ?? to match any byte (i.e. de??beef)") 70 | flag.Parse() 71 | 72 | quitCh := make(chan bool) 73 | sigCh := make(chan os.Signal, 1) 74 | signal.Notify(sigCh, os.Interrupt) 75 | go func(){ 76 | for _ = range sigCh { 77 | quitCh<-true // for jobs sender 78 | } 79 | }() 80 | 81 | ctrLogger = log.New(ctrWritter{new(int)}, "", 0) 82 | 83 | prometheusDecrypt(decOption{ 84 | inputFile: *inputFile, 85 | outputFile: *outputFile, 86 | startTick: *startTick, 87 | reversed: *reversed, 88 | useCurTick: *useCurTick, 89 | found: *found, 90 | backTime: *backTime, 91 | decSize: *decSize, 92 | key: *key, 93 | threadCount: *threadCount, 94 | format: *format, 95 | customSearch: *customSearch, 96 | bytesFormat: *bytesFormat, 97 | }, quitCh) 98 | } 99 | -------------------------------------------------------------------------------- /main.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | PerMonitorV2, PerMonitor 12 | True 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /main.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/main.syso -------------------------------------------------------------------------------- /main_gui.go: -------------------------------------------------------------------------------- 1 | // +build gui 2 | 3 | /* 4 | MIT License 5 | 6 | Copyright (c) 2021 CyCraft Technology 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | */ 26 | 27 | package main 28 | 29 | import( 30 | "log" 31 | "time" 32 | "math" 33 | "strings" 34 | "strconv" 35 | 36 | "github.com/lxn/walk" 37 | . "github.com/lxn/walk/declarative" 38 | ) 39 | 40 | var ctrLogger *log.Logger 41 | 42 | type logWritter struct { 43 | results *walk.TextEdit 44 | } 45 | 46 | func (w logWritter) Write(p []byte) (n int, err error) { 47 | w.results.AppendText(string(p) + "\r\n") 48 | return len(p), nil 49 | } 50 | 51 | type ctrWritter struct { 52 | ctrText *walk.TextLabel 53 | lastVal *int 54 | } 55 | 56 | func (w ctrWritter) Write(p []byte) (n int, err error) { 57 | strp := strings.TrimLeft(string(p), "\r") 58 | strp = strings.TrimRight(strp, "\n") 59 | intp, err := strconv.Atoi(strp) 60 | if (intp / 1000) != *w.lastVal { 61 | *w.lastVal = intp / 1000 62 | w.ctrText.SetText(strconv.Itoa(intp/1000) + "000...") 63 | } 64 | return len(p), nil 65 | } 66 | 67 | type mainWindow struct { 68 | *walk.MainWindow 69 | inputFile *walk.LineEdit 70 | outputFile *walk.LineEdit 71 | results *walk.TextEdit 72 | counter *walk.TextLabel 73 | // tickcount 74 | useCurTick *walk.CheckBox 75 | startTick *walk.CheckBox 76 | startTickNum *walk.NumberEdit 77 | useRevTick *walk.CheckBox 78 | // other strategy 79 | found *walk.CheckBox 80 | foundNum *walk.NumberEdit 81 | backTime *walk.CheckBox 82 | backTimeNum *walk.NumberEdit 83 | decSize *walk.CheckBox 84 | decSizeNum *walk.NumberEdit 85 | // key 86 | useKey *walk.CheckBox 87 | decKey *walk.LineEdit 88 | // thread 89 | useThread *walk.CheckBox 90 | threadCount *walk.NumberEdit 91 | // search target 92 | useExt *walk.CheckBox 93 | searchExt *walk.LineEdit 94 | useStr *walk.CheckBox 95 | searchStr *walk.LineEdit 96 | useBytes *walk.CheckBox 97 | searchBytes *walk.LineEdit 98 | // decrypt 99 | opt decOption 100 | quitCh chan bool 101 | running bool 102 | } 103 | 104 | func (mw *mainWindow) selectInputFile(){ 105 | dlg := &walk.FileDialog{} 106 | dlg.Title = "Select input file" 107 | dlg.Filter = "*.*" 108 | 109 | if _, err := dlg.ShowOpen(mw); err != nil { 110 | log.Println(err) 111 | return 112 | } 113 | mw.inputFile.SetText(dlg.FilePath) 114 | } 115 | 116 | func (mw *mainWindow) selectInputDir(){ 117 | dlg := &walk.FileDialog{} 118 | dlg.Title = "Select input folder" 119 | dlg.Filter = "*.*" 120 | 121 | if _, err := dlg.ShowBrowseFolder(mw); err != nil { 122 | log.Println(err) 123 | return 124 | } 125 | mw.inputFile.SetText(dlg.FilePath) 126 | } 127 | 128 | func (mw *mainWindow) selectOutputFile(){ 129 | dlg := &walk.FileDialog{} 130 | dlg.Title = "Select output file" 131 | dlg.Filter = "*.*" 132 | 133 | if _, err := dlg.ShowSave(mw); err != nil { 134 | log.Println(err) 135 | return 136 | } 137 | mw.outputFile.SetText(dlg.FilePath) 138 | } 139 | 140 | func (mw *mainWindow) selectOutputDir(){ 141 | dlg := &walk.FileDialog{} 142 | dlg.Title = "Select output folder" 143 | dlg.Filter = "*.*" 144 | 145 | if _, err := dlg.ShowBrowseFolder(mw); err != nil { 146 | log.Println(err) 147 | return 148 | } 149 | mw.outputFile.SetText(dlg.FilePath) 150 | } 151 | 152 | func (mw *mainWindow) selectUseCurTick(){ 153 | if mw.useCurTick.CheckState() == walk.CheckChecked { 154 | mw.startTick.SetCheckState(walk.CheckUnchecked) 155 | } 156 | } 157 | 158 | func (mw *mainWindow) selectStartTick(){ 159 | if mw.startTick.CheckState() == walk.CheckChecked { 160 | mw.useCurTick.SetCheckState(walk.CheckUnchecked) 161 | } 162 | } 163 | 164 | func (mw *mainWindow) nextOne(){ 165 | if mw.running { 166 | mw.quitCh<-true 167 | } 168 | } 169 | 170 | func (mw *mainWindow) decrypt(){ 171 | if mw.running { 172 | log.Println("It's decrypting now.") 173 | return 174 | } 175 | 176 | mw.opt.inputFile = mw.inputFile.Text() 177 | if mw.opt.inputFile == "Input file" { 178 | mw.opt.inputFile = "" 179 | } 180 | mw.opt.outputFile = mw.outputFile.Text() 181 | if mw.opt.outputFile == "Output file" { 182 | mw.opt.outputFile = "" 183 | } 184 | if mw.startTick.CheckState() == walk.CheckChecked { 185 | mw.opt.startTick = int(mw.startTickNum.Value()) 186 | } 187 | if mw.useRevTick.CheckState() == walk.CheckChecked { 188 | mw.opt.reversed = true 189 | } 190 | if mw.useCurTick.CheckState() == walk.CheckChecked { 191 | mw.opt.useCurTick = true 192 | } 193 | if mw.useKey.CheckState() == walk.CheckChecked { 194 | mw.opt.key = mw.decKey.Text() 195 | } 196 | if mw.useThread.CheckState() == walk.CheckChecked { 197 | mw.opt.threadCount = int(mw.threadCount.Value()) 198 | } 199 | if mw.useExt.CheckState() == walk.CheckChecked { 200 | mw.opt.format = mw.searchExt.Text() 201 | } 202 | if mw.useStr.CheckState() == walk.CheckChecked { 203 | mw.opt.customSearch = mw.searchStr.Text() 204 | } 205 | if mw.useBytes.CheckState() == walk.CheckChecked { 206 | mw.opt.bytesFormat = mw.searchBytes.Text() 207 | } 208 | if mw.found.CheckState() == walk.CheckChecked { 209 | mw.opt.found = int(mw.foundNum.Value()) 210 | } 211 | if mw.backTime.CheckState() == walk.CheckChecked { 212 | mw.opt.backTime = int(mw.backTimeNum.Value()) 213 | } 214 | if mw.decSize.CheckState() == walk.CheckChecked { 215 | mw.opt.decSize = int(mw.decSizeNum.Value()) 216 | } 217 | 218 | go func(){ 219 | mw.running = true 220 | prometheusDecrypt(mw.opt, mw.quitCh) 221 | mw.counter.SetText("Done!") 222 | mw.running = false 223 | }() 224 | } 225 | 226 | 227 | func main(){ 228 | mw := &mainWindow{ 229 | opt: decOption{ 230 | inputFile: "", 231 | outputFile: "", 232 | startTick: 0, 233 | reversed: false, 234 | useCurTick: false, 235 | found: 1, 236 | backTime: 10, 237 | decSize: -1, 238 | key: "", 239 | threadCount: 1, 240 | format: "", 241 | customSearch: "", 242 | bytesFormat: "", 243 | }, 244 | quitCh: make(chan bool), 245 | running: false, 246 | } 247 | 248 | // log to results (set after run) 249 | go func(){ 250 | time.Sleep(3 * time.Second) 251 | log.SetOutput(logWritter{mw.results}) 252 | ctrLogger = log.New(ctrWritter{mw.counter, new(int)}, "", 0) 253 | }() 254 | 255 | // mainWindow 256 | if _, err := (MainWindow{ 257 | AssignTo: &mw.MainWindow, 258 | Title: "Prometheus Decrypt", 259 | MinSize: Size{600, 400}, 260 | Layout: VBox{}, 261 | Children: []Widget{ 262 | // input & output 263 | GroupBox{ 264 | Title: "Select Input / Output File", 265 | Layout: VBox{}, 266 | Children: []Widget{ 267 | Composite{ 268 | Layout: HBox{}, 269 | Children: []Widget{ 270 | LineEdit{ 271 | Text: "Input file", 272 | AssignTo: &mw.inputFile, 273 | ReadOnly: true, 274 | }, 275 | PushButton{ 276 | Text: "select file", 277 | OnClicked: mw.selectInputFile, 278 | }, 279 | PushButton{ 280 | Text: "select folder", 281 | OnClicked: mw.selectInputDir, 282 | }, 283 | }, 284 | }, 285 | Composite{ 286 | Layout: HBox{}, 287 | Children: []Widget{ 288 | LineEdit{ 289 | Text: "Output file", 290 | AssignTo: &mw.outputFile, 291 | ReadOnly: true, 292 | }, 293 | PushButton{ 294 | MaxSize: Size{100, 20}, 295 | Text: "select file", 296 | OnClicked: mw.selectOutputFile, 297 | }, 298 | PushButton{ 299 | Text: "select folder", 300 | OnClicked: mw.selectOutputDir, 301 | }, 302 | }, 303 | }, 304 | }, 305 | }, 306 | // Option 307 | GroupBox{ 308 | Title: "Options", 309 | Layout: VBox{}, 310 | Children: []Widget{ 311 | Composite{ 312 | Layout: HBox{}, 313 | Children: []Widget{ 314 | GroupBox{ 315 | Title: "Search strategy", 316 | MinSize: Size{350, 100}, 317 | Layout: VBox{Alignment: AlignHNearVCenter}, 318 | Children: []Widget{ 319 | CheckBox { 320 | AssignTo: &mw.useCurTick, 321 | Text: "Use current tickcount", 322 | Checked: false, 323 | OnCheckedChanged: mw.selectUseCurTick, 324 | }, 325 | Composite{ 326 | Layout:HBox{Alignment: AlignHNearVCenter, MarginsZero: true}, 327 | Children: []Widget{ 328 | CheckBox { 329 | AssignTo: &mw.startTick, 330 | Text: "Start tickcount (default: 0)", 331 | Checked: false, 332 | OnCheckedChanged: mw.selectStartTick, 333 | }, 334 | NumberEdit { 335 | MinSize: Size{Width: 150}, 336 | MaxValue: math.MaxInt32, 337 | MinValue: 0, 338 | AssignTo: &mw.startTickNum, 339 | }, 340 | }, 341 | }, 342 | CheckBox { 343 | AssignTo: &mw.useRevTick, 344 | Text: "Reversed tickcount", 345 | Checked: false, 346 | OnCheckedChanged: func(){}, 347 | }, 348 | Composite{ 349 | Layout:HBox{Alignment: AlignHNearVCenter, MarginsZero: true}, 350 | Children: []Widget{ 351 | CheckBox { 352 | AssignTo: &mw.found, 353 | Text: "Found candidate (default: 1)", 354 | Checked: false, 355 | }, 356 | NumberEdit { 357 | MinSize: Size{Width: 150}, 358 | MaxValue: math.MaxInt32, 359 | MinValue: 1, 360 | AssignTo: &mw.foundNum, 361 | }, 362 | }, 363 | }, 364 | Composite{ 365 | Layout:HBox{Alignment: AlignHNearVCenter, MarginsZero: true}, 366 | Children: []Widget{ 367 | CheckBox { 368 | AssignTo: &mw.backTime, 369 | Text: "Seed move back (default: 10 min)", 370 | Checked: false, 371 | }, 372 | NumberEdit { 373 | MinSize: Size{Width: 150}, 374 | MaxValue: math.MaxInt32/1000/60, 375 | MinValue: 1, 376 | AssignTo: &mw.backTimeNum, 377 | }, 378 | }, 379 | }, 380 | Composite{ 381 | Layout:HBox{Alignment: AlignHNearVCenter, MarginsZero: true}, 382 | Children: []Widget{ 383 | CheckBox { 384 | AssignTo: &mw.decSize, 385 | Text: "Decrypt size (default: 100)", 386 | Checked: false, 387 | }, 388 | NumberEdit { 389 | MinSize: Size{Width: 150}, 390 | AssignTo: &mw.decSizeNum, 391 | }, 392 | }, 393 | }, 394 | }, 395 | }, 396 | Composite{ 397 | Layout: VBox{MarginsZero: true, SpacingZero: true}, 398 | Children: []Widget{ 399 | GroupBox{ 400 | Title: "Key", 401 | Layout: VBox{Alignment: AlignHNearVCenter}, 402 | Children: []Widget{ 403 | CheckBox { 404 | AssignTo: &mw.useKey, 405 | Text: "Key (use this key to decrypt it directly)", 406 | Checked: false, 407 | }, 408 | LineEdit { 409 | MaxSize: Size{Width: 150}, 410 | AssignTo: &mw.decKey, 411 | }, 412 | }, 413 | }, 414 | GroupBox{ 415 | Title: "Thread", 416 | Layout: VBox{Alignment: AlignHNearVCenter}, 417 | Children: []Widget{ 418 | CheckBox { 419 | AssignTo: &mw.useThread, 420 | Text: "Use Thread (please input amount of thread, max: 256)", 421 | Checked: false, 422 | }, 423 | NumberEdit { 424 | MaxSize: Size{Width: 150}, 425 | MaxValue: 256, 426 | MinValue: 1, 427 | AssignTo: &mw.threadCount, 428 | }, 429 | }, 430 | }, 431 | }, 432 | }, 433 | }, 434 | }, 435 | GroupBox{ 436 | Title: "Search Target", 437 | Layout: VBox{}, 438 | Children: []Widget{ 439 | Composite{ 440 | Layout:HBox{Alignment: AlignHNearVCenter, MarginsZero: true}, 441 | Children: []Widget{ 442 | CheckBox { 443 | AssignTo: &mw.useExt, 444 | Text: "Search extension", 445 | Checked: false, 446 | OnCheckedChanged: func(){}, 447 | }, 448 | LineEdit { 449 | Alignment: AlignHFarVCenter, 450 | MaxSize: Size{Width: 300}, 451 | AssignTo: &mw.searchExt, 452 | }, 453 | }, 454 | }, 455 | Composite{ 456 | Layout:HBox{Alignment: AlignHNearVCenter, MarginsZero: true}, 457 | Children: []Widget{ 458 | CheckBox { 459 | AssignTo: &mw.useStr, 460 | Text: "Search string", 461 | Checked: false, 462 | OnCheckedChanged: func(){}, 463 | }, 464 | LineEdit { 465 | Alignment: AlignHFarVCenter, 466 | MaxSize: Size{Width: 300}, 467 | AssignTo: &mw.searchStr, 468 | }, 469 | }, 470 | }, 471 | Composite{ 472 | Layout:HBox{Alignment: AlignHNearVCenter, MarginsZero: true}, 473 | Children: []Widget{ 474 | CheckBox { 475 | AssignTo: &mw.useBytes, 476 | Text: "Search bytes string", 477 | Checked: false, 478 | OnCheckedChanged: func(){}, 479 | }, 480 | LineEdit { 481 | Alignment: AlignHFarVCenter, 482 | MaxSize: Size{Width: 300}, 483 | AssignTo: &mw.searchBytes, 484 | }, 485 | }, 486 | }, 487 | }, 488 | }, 489 | }, 490 | }, 491 | // Decrypt 492 | Composite{ 493 | Layout: HBox{}, 494 | Children: []Widget{ 495 | PushButton{ 496 | Text: "Decrypt", 497 | OnClicked: mw.decrypt, 498 | }, 499 | PushButton{ 500 | Text: "Next one", 501 | OnClicked: mw.nextOne, 502 | }, 503 | TextLabel{ 504 | AssignTo: &mw.counter, 505 | }, 506 | }, 507 | }, 508 | // result 509 | TextEdit{ 510 | AssignTo: &mw.results, 511 | ReadOnly: true, 512 | HScroll: true, 513 | VScroll: true, 514 | MinSize: Size{Height: 200}, 515 | }, 516 | TextLabel{ 517 | Alignment: AlignHFarVCenter, 518 | Text: "powered by CyCraft Technology", 519 | }, 520 | }, 521 | }.Run()); err != nil { 522 | log.Fatal(err) 523 | } 524 | } 525 | 526 | 527 | -------------------------------------------------------------------------------- /output/103171375_file-example_PDF_500_kB.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/output/103171375_file-example_PDF_500_kB.pdf -------------------------------------------------------------------------------- /output/103171406_file-sample_500kB.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/output/103171406_file-sample_500kB.docx -------------------------------------------------------------------------------- /output/103171437_file_example_AVI_480_750kB.avi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/output/103171437_file_example_AVI_480_750kB.avi -------------------------------------------------------------------------------- /output/103171468_file_example_JPG_500kB.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/output/103171468_file_example_JPG_500kB.jpg -------------------------------------------------------------------------------- /output/103171500_file_example_MP4_480_1_5MG.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/output/103171500_file_example_MP4_480_1_5MG.mp4 -------------------------------------------------------------------------------- /output/103171562_file_example_PPT_1MB.ppt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/output/103171562_file_example_PPT_1MB.ppt -------------------------------------------------------------------------------- /output/103171640_file_example_XLSX_50.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/output/103171640_file_example_XLSX_50.xlsx -------------------------------------------------------------------------------- /output/103171671_zip_2MB.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/output/103171671_zip_2MB.zip -------------------------------------------------------------------------------- /output/615750_CyCraft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/output/615750_CyCraft.png -------------------------------------------------------------------------------- /output/615750_test.txt: -------------------------------------------------------------------------------- 1 | Black Lives Matter. Support the Equal Justice Initiative. 2 | Go 3 | Documents 4 | Packages 5 | The Project 6 | Help 7 | Blog 8 | Play 9 | Next article 10 | 11 | Fuzzing is Beta Ready 12 | 13 | Previous article 14 | 15 | Contexts and structs 16 | 17 | Links 18 | 19 | golang.org 20 | Install Go 21 | A Tour of Go 22 | Go Documentation 23 | Go Mailing List 24 | Go on Twitter 25 | Blog index 26 | 27 | The Go Blog 28 | 29 | Go Developer Survey 2020 Results 30 | 31 | Alice Merrick 32 | 9 March 2021 33 | 34 | Thank you for the amazing response! 35 | 36 | In 2020, we had another great turnout with 9,648 responses, about as many as 2019. Thank you for putting in the time to provide the community with these insights on your experiences using Go! 37 | 38 | New modular survey design 39 | 40 | You may notice some questions have smaller sample sizes ("n=") than others. That's because some questions were shown to everyone while others were only shown to a random subset of respondents. 41 | 42 | Highlights 43 | 44 | Go usage is expanding in the workplace and enterprise with 76% of respondents using Go at work and 66% saying Go is critical to their company's success. 45 | Overall satisfaction is high with 92% of respondents being satisfied using Go. 46 | The majority of respondents felt productive in Go in less than 3 months, with 81% feeling very or extremely productive in Go. 47 | Respondents reported upgrading promptly to the latest Go version, with 76% in the first 5 months. 48 | Respondents using pkg.go.dev are more successful (91%) at finding Go packages than non-users (82%). 49 | Go modules adoption is nearly universal with 77% satisfaction, but respondents also highlight a need for improved docs. 50 | Go continues to be heavily used for APIs, CLIs, Web, DevOps & Data Processing. 51 | Underrepresented groups tend to feel less welcome in the community. 52 | Who did we hear from? 53 | 54 | Demographic questions help us distinguish which year-over-year differences may result from changes in who responded to the survey versus changes in sentiment or behavior. Because our demographics are similar to last year, we can be reasonably confident that other year-over-year changes aren't primarily due to demographic shifts. 55 | 56 | For example, the distribution of organization sizes, developer experience, and industries remained about the same from 2019 to 2020. 57 | 58 | Bar chart of organization size for 2019 to 2020 where the majority have fewer than 1000 employees Bar chart of years of professional experience for 2019 to 2020 with the majority having 3 to 10 years of experience Bar chart of organization industries for 2019 to 2020 with the majority in Technology 59 | Almost half (48%) of respondents have been using Go for less than two years. In 2020, we had fewer responses from those using Go for less than a year. 60 | 61 | Bar chart of years of experience using Go 62 | Majorities said they use Go at work (76%) and outside of work (62%). The percentage of respondents using Go at work has been trending up each year. 63 | 64 | Bar chart where Go is being used at work or outside of work 65 | This year we introduced a new question on primary job responsibilities. We found that 70% of respondents’ primary responsibility is developing software and applications, but a significant minority (10%) are designing IT systems and architectures. 66 | 67 | Primary job responsibilities 68 | As in prior years, we found that most respondents are not frequent contributors to Go open-source projects, with 75% saying they do so "infrequently" or "never". 69 | 70 | How often respondents contribute to open source projects written in Go from 2017 to 2020 where results remain about the same each year and only 7% contribute daily 71 | Developer tools and practices 72 | 73 | As in prior years, the vast majority of survey respondents reported working with Go on Linux (63%) and macOS (55%) systems. The proportion of respondents who primarily develop on Linux appears to be slightly trending down over time. 74 | 75 | Primary operating system from 2017 to 2020 76 | For the first time, editor preferences appear to have stabilized: VS Code remains the most preferred editor (41%), with GoLand a strong second (35%). Together these editors made up 76% of responses, and other preferences did not continue to decrease as they had in previous years. 77 | 78 | Editor preferences from 2017 to 2020 79 | This year we asked respondents to prioritize improvements to their editor by how much they would hypothetically spend if they had 100 “GopherCoins” (a fictional currency). Code completion received the highest average number of GopherCoins per respondent. Half of respondents gave the top 4 features (code completion, navigating code, editor performance and refactoring) 10 or more coins. 80 | 81 | Bar char of average number of GopherCoins spent per respondent 82 | A majority of respondents (63%) spend 10–30% of their time refactoring, suggesting that this is a common task and we want to investigate ways to improve it. It also explains why refactoring support was one of the most-funded editor improvements. 83 | 84 | Bar chart of time spent refactoring 85 | Last year we asked about specific developer techniques and found that almost 90% of respondents were using text logging for debugging, so this year we added a follow-up question to find out why. Results show that 43% use it because it allows them to use the same debugging strategy across different languages, and 42% prefer to use text logging over other debugging techniques. However, 27% don't know how to get started with Go's debugging tools and 24% have never tried using Go's debugging tools, so there's an opportunity to improve the debugger tooling in terms of discoverability, usability and documentation. Additionally, because a quarter of respondents have never tried using debugging tools, pain points may be underreported. 86 | 87 | 88 | Sentiments towards Go 89 | 90 | For the first time, this year we asked about overall satisfaction. 92% of respondents said they were very or somewhat satisfied using Go during the past year. 91 | 92 | Bar chart of overall satisfaction on a 5 points scale from very dissatisfied to very satisfied 93 | This is the 3rd year we've asked the "Would you recommend…" Net Promoter Score (NPS) question. This year our NPS result is a 61 (68% "promoters" minus 6% "detractors"), statistically unchanged from 2019 and 2018. 94 | 95 | Stacked bar chart of promoters, passives, and detractors 96 | Similar to previous years, 91% of respondents said they would prefer to use Go for their next new project. 89% said Go is working well for their team. This year we saw an increase in respondents who agreed that Go is critical to their company’s success from 59% in 2019 to 66% in 2020. Respondents working at organizations of 5,000 or more employees were less likely to agree (63%), while those at smaller organizations were more likely to agree (73%). 97 | 98 | Bar chart of agreement with statements I would prefer to use Go for my next project, Go is working well for me team, 89%, and Go is critical to my company's success 99 | Like last year, we asked respondents to rate specific areas of Go development according to satisfaction and importance. Satisfaction with using cloud services, debugging, and using modules (areas that last year were highlighted as opportunities for improvement) increased while most importance scores remained about the same. We also introduced a couple new topics: API and Web frameworks. We see that web frameworks satisfaction is lower than other areas (64%). It wasn't as critically important to most current users (only 28% of respondents said it was very or critically important), but it could be a missing critical feature for would-be Go developers. 100 | 101 | Bar chart of satisfaction with aspects of Go from 2019 to 2020, showing highest satisfaction with build speed, reliability and using concurrency and lowest with web frameworks 102 | 81% of respondents said they felt very or extremely productive using Go. Respondents at larger organizations were more likely to feel extremely productive than those at smaller organizations. 103 | 104 | Stacked bar chart of perceived productivity on 5 point scale from not all to extremely productive 105 | We’ve heard anecdotally that it’s easy to become productive quickly with Go. We asked respondents who felt at least slightly productive how long it took them to become productive. 93% said it took less than one year, with the majority feeling productive within 3 months. 106 | 107 | Bar chart of length of time before feeling productive 108 | Although about the same as last year, the percentage of respondents who agreed with the statement "I feel welcome in the Go community" appears to be trending down over time, or at least not holding to the same upward trends as other areas. 109 | 110 | We've also seen a significant year-over-year increase in the proportion of respondents who feel Go’s project leadership understands their needs (63%). 111 | 112 | All of these results show a pattern of higher agreement correlated with increased Go experience, beginning at about two years. In other words, the longer a respondent has been using Go, the more likely they were to agree with each of these statements. 113 | 114 | Bar chart showing agreement with statements I feel welcome in the Go community, I am confident in the Go leadership, I feel welcome to contribute, The Go project leadership understands my needs, and The process of contributing to the Go project is clear to me 115 | We asked an open text question on what we could do to make the Go community more welcoming and the most common recommendations (21%) were related to different forms of or improvements/additions to learning resources and documentation. 116 | 117 | Bar chart of recommendations for improving the welcomeness of the Go community 118 | Working with Go 119 | 120 | Building API/RPC services (74%) and CLIs (65%) remain the most common uses of Go. We don't see any significant changes from last year, when we introduced randomization into the ordering of options. (Prior to 2019, options towards the beginning of the list were disproportionately selected.) We also broke this out by organization size and found that respondents use Go similarly at large enterprises or smaller organizations, although large orgs are a little less likely to use Go for web services returning HTML. 121 | 122 | Bar chart of Go use cases from 2019 to 2020 including API or RPC services, CLIs, frameworks, web services, automation, agents and daemons, data processing, GUIs, games and mobile apps 123 | This year we now have a better understanding of which kinds of software respondents write in Go at home versus at work. Although web services returning HTML is the 4th most common use case, this is due to non-work related use. More respondents use Go for automation/scripts, agents and daemons, and data processing for work than web services returning HTML. A greater proportion of the least common uses (desktop/GUI apps, games, and mobile apps) are being written outside of work. 124 | 125 | Stacked bar charts of proportion of use case is at work, outside of work, or both 126 | Another new question asked how satisfied respondents were for each use case. CLIs had the highest satisfaction, with 85% of respondents saying they were very, moderately or slightly satisfied using Go for CLIs. Common uses for Go tended to have higher satisfaction scores, but satisfaction and popularity don’t perfectly correspond. For example, agents and daemons has 2nd highest proportion of satisfaction but it’s 6th in usage. 127 | 128 | Bar chart of satisfaction with each use case 129 | Additional follow-up questions explored different use cases, for example, which platforms respondents target with their CLIs. It's not surprising to see Linux (93%) and macOS (59%) highly represented, given the high developer use of Linux and macOS and high Linux cloud usage), but even Windows is targeted by almost a third of CLI developers. 130 | 131 | Bar chart of platforms being targeted for CLIs 132 | A closer look at Go for data processing showed that Kafka is the only broadly adopted engine, but a majority of respondents said they use Go with a custom data processing engine. 133 | 134 | Bar chart of data processing engines used by those who use Go for data processing 135 | We also asked about larger areas in which respondents work with Go. The most common area by far was web development (68%), but other common areas included databases (46%), DevOps (42%) network programming (41%) and systems programming (40%). 136 | 137 | Bar chart of the kind of work where Go is being used 138 | Similar to last year, we found that 76% of respondents evaluate the current Go release for production use, but this year we refined our time scale and found that 60% begin evaluating a new version before or within 2 months of release. This highlights the importance for platform-as-a-service providers to quickly support new stable releases of Go. 139 | 140 | Bar chart of how soon respondents begin evaluating a new Go release 141 | Modules 142 | 143 | This year we found near-universal adoption for Go modules, and a significant increase in the proportion of respondents who only use modules for package management. 96% of respondents said they were using modules for package management, up from 89% last year. 87% of respondents said they were using only modules for package management, up from 71% last year. Meanwhile, the use of other package management tools has decreased. 144 | 145 | Bar chart of methods used for Go package management 146 | Satisfaction with modules also increased from last year. 77% of respondents said they were very, moderately or slightly satisfied with modules, compared to 68% in 2019. 147 | 148 | Stacked bar chart of satisfaction with using modules on a 7 point scale from very dissatisfied to very satisfied 149 | Official documentation 150 | 151 | Most respondents said they struggle with official documentation. 62% of respondents struggle to find enough information to fully implement a feature of their application and over a third have struggled to get started with something they haven’t done before. 152 | 153 | Bar chart of struggles using official Go documentation 154 | The most problematic areas of official documentation were on using modules and CLI development, with 20% of respondents finding modules documentation slightly or not at all helpful, and 16% for documentation around CLI development. 155 | 156 | Stacked bar charts on helpfulness of specific areas of documentation including using modules, CLI tool development, error handling, web service development, data access, concurrency and file input/output, rated on a 5 point scale from not at all to very helpful 157 | Go in the clouds 158 | 159 | Go was designed with modern distributed computing in mind, and we want to continue to improve the developer experience of building cloud services with Go. 160 | 161 | The three largest global cloud providers (Amazon Web Services, Google Cloud Platform, and Microsoft Azure) continue to increase in usage among survey respondents, while most other providers are used by a smaller proportion of respondents each year. Azure in particular had a significant increase from 7% to 12%. 162 | On-prem deployments to self-owned or company-owned servers continue to decrease as the most common deployment targets. 163 | Bar chart of cloud providers used to deploy Go programs where AWS is the most common at 44% 164 | Respondents deploying to AWS and Azure saw increases in deploying to a managed Kubernetes platform, now at 40% and 54%, respectively. Azure saw a significant drop in the proportion of users deploying Go programs to VMs and some growth in container usage from 18% to 25%. Meanwhile, GCP (which already had a high proportion of respondents reporting managed Kubernetes use) saw some growth in deploying to serverless Cloud Run from 10% to 17%. 165 | 166 | Bar charts of proportion of services being used with each provider 167 | Overall, a majority of respondents were satisfied with using Go on all three major cloud providers, and the figures are statistically unchanged from last year. Respondents reported similar satisfaction levels with Go development for AWS (82% satisfied) and GCP (80%). Azure received a lower satisfaction score (58% satisfied), and free-text responses often cited a need for improvements to Azure's Go SDK and Go support for Azure functions. 168 | 169 | Stacked bar chart of satisfaction with using Go with AWS, GCP and Azure 170 | Pain points 171 | 172 | The top reasons respondents say they are unable to use Go more remain working on a project in another language (54%), working on a team that prefers to use another language (34%), and the lack of a critical feature in Go itself (26%). 173 | 174 | This year we introduced a new option, “I already use Go everywhere I would like to,” so that respondents could opt out of making selections that don't prevent them from using Go. This significantly lowered the rate of selection of all other options, but did not change their relative ordering. We also introduced an option for “Go lacks critical frameworks”. 175 | 176 | If we look at only the respondents who selected reasons for not using Go, we can get a better idea of year-over-year trends. Working on an existing project in another language and project/team/lead preference for another language are decreasing over time. 177 | 178 | Bar charts of reasons preventing respondents from using Go more 179 | Among the 26% of respondents who said Go lacks language features they need, 88% selected generics as a critical missing feature. Other critical missing features were better error handling (58%), null safety (44%), functional programming features(42%) and a stronger / expanded type system (41%). 180 | 181 | To be clear, these numbers are from the subset of respondents who said they would be able to use Go more were it not missing one or more critical features they need, not the entire population of survey respondents. To put that in perspective, 18% of respondents are prevented from using Go because of a lack of generics. 182 | 183 | Bar chart of missing critical features 184 | The top challenge respondents reported when using Go was again Go's lack of generics (18%), while modules/package management and problems with learning curve/best practices/docs were both 13%. 185 | 186 | Bar chart of biggest challenges respondents face when using Go 187 | The Go community 188 | 189 | This year we asked respondents for their top 5 resources for answering their Go-related questions. Last year we only asked for top 3, so the results aren't directly comparable, however, StackOverflow remains the most popular resource at 65%. Reading source code (57%) remains another popular resource while reliance on godoc.org (39%) has significantly decreased. The package discovery site pkg.go.dev is new to the list this year and was a top resource for 32% of respondents. Respondents who use pkg.go.dev are more likely to agree they are able to quickly find Go packages / libraries they need: 91% for pkg.go.dev users vs. 82% for everyone else. 190 | 191 | Bar chart of top 5 resources respondents use to answer Go-related questions 192 | Over the years, the proportion of respondents who do not attend any Go-related events has been trending up. Due to Covid-19, this year we modified our question around Go events, and found over a quarter of respondents have spent more time in online Go channels than in prior years, and 14% attended a virtual Go meetup, twice as many as last year. 64% of those who attended a virtual event said this was their first virtual event. 193 | 194 | Bar chart of respondents participation in online channels and events 195 | We found 12% of respondents identify with a traditionally underrepresented group (e.g., ethnicity, gender identity, et al.), the same as 2019, and 2% identify as women, fewer than in 2019 (3%). Respondents who identified with underrepresented groups showed higher rates of disagreement with the statement "I feel welcome in the Go community" (10% vs. 4%) than those who do not identify with an underrepresented group. These questions allow us to measure diversity in the community and highlight opportunities for outreach and growth. 196 | 197 | Bar chart of underrepresented groups Bar chart of those who identify as women Bar chart of welcomeness of underrepresented groups 198 | We added an additional question this year on assistive technology usage, and found that 8% of respondents are using some form of assistive technology. The most commonly used assistive tech was contrast or color settings (2%). This is a great reminder that we have users with accessibility needs and helps drive some of our design decisions on websites managed by the Go team. 199 | 200 | Bar chart of assistive technology usage 201 | The Go team values diversity and inclusion, not simply as the right thing to do, but because diverse voices can illuminate our blindspots and ultimately benefit all users. The way we ask about sensitive information, including gender and traditionally underrepresented groups, has changed according to data privacy regulations and we hope to make these questions, particularly around gender diversity, more inclusive in the future. 202 | 203 | Conclusion 204 | 205 | Thank you for joining us in reviewing the results of our 2020 developer survey! Understanding developers’ experiences and challenges helps us measure our progress and directs the future of Go. Thanks again to everyone who contributed to this survey—we couldn't have done it without you. We hope to see you next year! 206 | 207 | Related articles 208 | 209 | Announcing the 2020 Go Developer Survey 210 | Go Developer Survey 2019 Results 211 | Proposals for Go 1.15 212 | Announcing the 2019 Go Developer Survey 213 | Contributors Summit 2019 214 | Experiment, Simplify, Ship 215 | Next steps toward Go 2 216 | Go 2018 Survey Results 217 | Go 2, here we come! 218 | Nine years of Go 219 | Participate in the 2018 Go User Survey 220 | Participate in the 2018 Go Company Questionnaire 221 | Go 2 Draft Designs 222 | Go 2017 Survey Results 223 | Hello, 中国! 224 | Participate in the 2017 Go User Survey 225 | Eight years of Go 226 | Community Outreach Working Group 227 | Contribution Workshop 228 | Contributors Summit 229 | Toward Go 2 230 | Go 2016 Survey Results 231 | Participate in the 2016 Go User Survey and Company Questionnaire 232 | Go, Open Source, Community 233 | GopherChina Trip Report 234 | Four years of Go 235 | Get thee to a Go meetup 236 | Go turns three 237 | Getting to know the Go community 238 | The Go Programming Language turns two 239 | Spotlight on external Go libraries 240 | Third-party libraries: goprotobuf and beyond 241 | The Go Gopher 242 | Copyright Terms of Service Privacy Policy Report issue 243 | Supported by Google 244 | -------------------------------------------------------------------------------- /prometheus_decrypt.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 CyCraft Technology 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | package main 26 | 27 | import( 28 | "golang.org/x/crypto/salsa20" 29 | "github.com/h2non/filetype" 30 | "prometheus_decrypt/csharp_random" 31 | "prometheus_decrypt/examine" 32 | "prometheus_decrypt/winsup" 33 | "fmt" 34 | "io/ioutil" 35 | "log" 36 | "math" 37 | "path/filepath" 38 | "os" 39 | "strings" 40 | "sync" 41 | ) 42 | 43 | type decOption struct { 44 | inputFile string 45 | outputFile string 46 | startTick int 47 | reversed bool 48 | useCurTick bool 49 | found int 50 | backTime int 51 | decSize int 52 | key string 53 | threadCount int 54 | format string 55 | customSearch string 56 | bytesFormat string 57 | } 58 | 59 | const HEADER_MAX_SIZE = 100 // except document 60 | 61 | func genKey(seed int32) [32]byte { 62 | var key [32]byte 63 | cr := csharp_random.Random(seed) 64 | for i:=0; i<32; i++ { 65 | v := cr.Next(33, 127) % 255 66 | if v == 34 || v == 92 { 67 | i -= 1 68 | } else { 69 | key[i] = byte(v) 70 | } 71 | } 72 | return key 73 | } 74 | 75 | func writeFile(data []byte, path string, seed int32, key string) error { 76 | dir, file := filepath.Split(path) 77 | writePath := fmt.Sprintf("%s%d_%s", dir, seed, file) 78 | // create all dir 79 | err := os.MkdirAll(dir, 0755) 80 | if err != nil { 81 | return err 82 | } 83 | // write file 84 | err = ioutil.WriteFile(writePath, data, 0644) 85 | log.Printf("\rDecrypt file with seed %d, key: %s, path: %s\n", seed, key, writePath) 86 | return err 87 | } 88 | 89 | func decRoutine(jobs chan int32, result chan int32, file []byte, output string, exam *examine.TypeExam, wg *sync.WaitGroup, decSize int) { 90 | defer wg.Done() 91 | plain := make([]byte, len(file)) 92 | for{ 93 | if seed, ok := <-jobs; ok { 94 | ctrLogger.Printf("\r%d", seed) 95 | key := genKey(seed) 96 | salsa20.XORKeyStream(plain, file[0:decSize], []byte{1, 2, 3, 4, 5, 6, 7, 8}, &key) 97 | if exam.Match(plain) { 98 | // the file header matches -> decrypt the whole file now 99 | salsa20.XORKeyStream(plain, file, []byte{1, 2, 3, 4, 5, 6, 7, 8}, &key) 100 | err := writeFile(plain, output, seed, string(key[:])) 101 | if err != nil { 102 | log.Println(err) 103 | } 104 | result<-seed 105 | } 106 | } else { 107 | break 108 | } 109 | } 110 | } 111 | 112 | func decWithoutKey(opt decOption, quitCh chan bool) int32 { 113 | // catch local error 114 | defer func(){ 115 | // do nothing just return 116 | recover() 117 | }() 118 | 119 | log.Println("Start decrypt", opt.inputFile) 120 | 121 | // local check 122 | if opt.customSearch == "" && opt.bytesFormat == "" && !filetype.IsSupported(opt.format) { 123 | log.Panic("Unsupported format. Please provide a custom search regular expression with -s.") 124 | } 125 | 126 | // build examine 127 | exam := examine.Init(opt.format, opt.customSearch, opt.bytesFormat) 128 | 129 | // Read input file 130 | file, err := ioutil.ReadFile(opt.inputFile) 131 | if err != nil { 132 | log.Panic(err) 133 | } 134 | 135 | // check decrypt size 136 | switch opt.decSize { 137 | case -1: // max header size according to github.com/h2non/filetype) 138 | if opt.format == "docx" || opt.format == "xlsx" || opt.format == "pptx" { 139 | opt.decSize = len(file) 140 | } else { 141 | opt.decSize = HEADER_MAX_SIZE 142 | } 143 | case 0: // full file size 144 | opt.decSize = len(file) 145 | default: 146 | if opt.decSize < 0 { 147 | opt.decSize = - opt.decSize 148 | } 149 | } 150 | if opt.decSize > len(file) { 151 | opt.decSize = len(file) 152 | } 153 | 154 | // start worker 155 | var wg sync.WaitGroup 156 | wg.Add(opt.threadCount) 157 | jobs := make(chan int32, opt.threadCount) 158 | result := make(chan int32, opt.threadCount) 159 | for i:=0; i math.MaxInt32 { 181 | i = 0 182 | } 183 | } 184 | 185 | if i == opt.startTick { 186 | end = true 187 | } 188 | } 189 | } 190 | close(jobs) 191 | }() 192 | 193 | // wait for job 194 | var lastTick int32 = -1 195 | found := 0 196 | go func(){ 197 | for true { 198 | if tick, ok := <-result; ok { 199 | lastTick = tick 200 | found++ 201 | if found == opt.found { 202 | quitCh<-true 203 | } 204 | } else { 205 | break 206 | } 207 | } 208 | }() 209 | 210 | wg.Wait() 211 | close(result) 212 | 213 | return lastTick 214 | } 215 | 216 | func decWithKey(opt decOption){ 217 | // catch local error 218 | defer func(){ 219 | // do nothing just return 220 | recover() 221 | }() 222 | 223 | file, err := ioutil.ReadFile(opt.inputFile) 224 | if err != nil { 225 | log.Panic(err) 226 | } 227 | plain := make([]byte, len(file)) 228 | var key_b [32]byte 229 | copy(key_b[:], []byte(opt.key)[:32]) 230 | salsa20.XORKeyStream(plain, file, []byte{1, 2, 3, 4, 5, 6, 7, 8}, &key_b) 231 | err = ioutil.WriteFile(opt.outputFile, plain, 0644) 232 | if err != nil { 233 | log.Panic(err) 234 | } 235 | } 236 | 237 | func prometheusDecrypt(opt decOption, quitCh chan bool){ 238 | // catch global error 239 | defer func(){ 240 | // do nothing just return 241 | recover() 242 | }() 243 | 244 | if opt.inputFile == "" || opt.outputFile == "" { 245 | log.Panic("Please provide input file path and output file path") 246 | } 247 | 248 | // check file or dir 249 | files := make([]struct{i string; o string}, 0) 250 | if fstatI, err := os.Stat(opt.inputFile); err != nil { 251 | log.Panic("Open input file failed:", err) 252 | } else if fstatI.IsDir() { 253 | if fstatO, err := os.Stat(opt.outputFile); err != nil{ 254 | log.Panic("Open output file failed:", err) 255 | } else if !fstatO.IsDir() { 256 | log.Panic("Input path and output path type should be the same.") 257 | } else { 258 | // generate all files in dir 259 | err = filepath.Walk(opt.inputFile, func(path string, info os.FileInfo, err error) error { 260 | if !info.IsDir() { 261 | path, err := filepath.Rel(opt.inputFile, path) 262 | if err != nil { 263 | return err 264 | } 265 | files = append(files, struct{i string; o string}{ 266 | filepath.Join(opt.inputFile, path), 267 | filepath.Join(opt.outputFile, path), 268 | }) 269 | } 270 | return nil 271 | }) 272 | if err != nil { 273 | log.Panic("Parse path failed:", err) 274 | } 275 | } 276 | } else { 277 | files = append(files, struct{i string; o string}{opt.inputFile, opt.outputFile}) 278 | } 279 | 280 | if opt.key != "" { // decrypt file with the key 281 | for _, file := range files { 282 | tmpOpt := opt 283 | opt.inputFile = file.i 284 | opt.outputFile = file.o 285 | decWithKey(tmpOpt) 286 | } 287 | } else { // guess key 288 | // global check 289 | if opt.threadCount <= 0 { 290 | log.Panic("Please provide a positive integer.") 291 | } else if len(opt.bytesFormat) % 2 == 1 { 292 | log.Panic("Length of bytes format should be a multiple of 2.") 293 | } else if opt.found <= 0 { 294 | log.Panic("Candidate found should be greater than 0.") 295 | } 296 | 297 | // set global startTick 298 | if opt.startTick < 0 { 299 | opt.startTick = - opt.startTick 300 | } 301 | if opt.startTick > math.MaxInt32 { 302 | log.Panic("Tick count should between -2147483648 and 2147483648.") 303 | } 304 | 305 | if opt.useCurTick { 306 | opt.startTick = winsup.GetTickCount() 307 | } 308 | 309 | // set backtime to millisecond 310 | opt.backTime *= 1000*60 311 | 312 | // decrypt each files 313 | var tick int = opt.startTick 314 | for _, file := range files { 315 | tmpOpt := opt 316 | tmpOpt.inputFile = file.i 317 | tmpOpt.outputFile = file.o 318 | // file format 319 | if tmpOpt.format == "" && tmpOpt.customSearch == "" && tmpOpt.bytesFormat == "" { 320 | tmpOpt.format = filepath.Ext(strings.Split(file.i, ".PROM")[0]) 321 | if len(tmpOpt.format) != 0 { 322 | tmpOpt.format = tmpOpt.format[1:] 323 | } 324 | } 325 | tmpOpt.format = strings.ToLower(tmpOpt.format) 326 | // startTick 327 | if tmpOpt.reversed { 328 | if tick+tmpOpt.backTime < tmpOpt.startTick { 329 | tmpOpt.startTick = tick+tmpOpt.backTime 330 | } 331 | } else { 332 | if tick-tmpOpt.backTime > tmpOpt.startTick { 333 | tmpOpt.startTick = tick-tmpOpt.backTime 334 | } 335 | } 336 | 337 | lastTick := int(decWithoutKey(tmpOpt, quitCh)) 338 | if lastTick != -1 { 339 | tick = lastTick 340 | } 341 | } 342 | } 343 | } 344 | 345 | 346 | -------------------------------------------------------------------------------- /sample/CyCraft.png.PROM[prometheushelp@mail.ch]: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/sample/CyCraft.png.PROM[prometheushelp@mail.ch] -------------------------------------------------------------------------------- /sample/README.md: -------------------------------------------------------------------------------- 1 | # Sample 2 | 3 | ## CyCraft.png.PROM[prometheushelp@mail.ch] 4 | ``` 5 | ./prometheus_decrypt -i ./sample/CyCraft.png.PROM\[prometheushelp@mail.ch\] -o ./output/CyCraft.png -e png -p 16 6 | ``` 7 | 8 | ## test.txt.enc 9 | ``` 10 | ./prometheus_decrypt -i ./sample/test.txt.enc -o ./output/test.txt -p 16 -s "we had another great" 11 | ``` 12 | 13 | ## file_example_AVI_480_750kB.avi.PROM[prometheushelp@mail.ch] 14 | ``` 15 | ./prometheus_decrypt -i ./sample/file_example_AVI_480_750kB.avi.PROM\[prometheushelp@mail.ch\] -o ./output/file_example_AVI_480_750kB.avi -p 16 -t 103000000 -e avi 16 | ``` 17 | 18 | ## file_example_JPG_500kB.jpg.PROM\[prometheushelp@mail.ch\] 19 | ``` 20 | ./prometheus_decrypt -i ./sample/file_example_JPG_500kB.jpg.PROM\[prometheushelp@mail.ch\] -o ./output/file_example_JPG_500kB.jpg -p 16 -t 103000000 -e jpg 21 | ``` 22 | 23 | ## file_example_MP4_480_1_5MG.mp4.PROM\[prometheushelp@mail.ch\] 24 | ``` 25 | ./prometheus_decrypt -i ./sample/file_example_MP4_480_1_5MG.mp4.PROM\[prometheushelp@mail.ch\] -o ./output/file_example_MP4_480_1_5MG.mp4 -p 16 -t 103000000 -e mp4 26 | ``` 27 | 28 | ## file-example_PDF_500_kB.pdf.PROM\[prometheushelp@mail.ch\] 29 | ``` 30 | ./prometheus_decrypt -i ./sample/file-example_PDF_500_kB.pdf.PROM\[prometheushelp@mail.ch\] -o ./output/file-example_PDF_500_kB.pdf -p 16 -t 103000000 -e pdf 31 | ``` 32 | 33 | ## file_example_PPT_1MB.ppt.PROM\[prometheushelp@mail.ch\] 34 | ``` 35 | ./prometheus_decrypt -i ./sample/file_example_PPT_1MB.ppt.PROM\[prometheushelp@mail.ch\] -o ./output/file_example_PPT_1MB.ppt -p 16 -t 103000000 -b 'd0cf11e0a1b11ae1' 36 | ``` 37 | 38 | ## file_example_XLSX_50.xlsx.PROM\[prometheushelp@mail.ch\] 39 | ``` 40 | ./prometheus_decrypt -i ./sample/file_example_XLSX_50.xlsx.PROM\[prometheushelp@mail.ch\] -o ./output/file_example_XLSX_50.xlsx -p 16 -t 103000000 -e xlsx 41 | ``` 42 | 43 | ## file-sample_500kB.docx.PROM\[prometheushelp@mail.ch\] 44 | ``` 45 | ./prometheus_decrypt -i ./sample/file-sample_500kB.docx.PROM\[prometheushelp@mail.ch\] -o ./output/file-sample_500kB.docx -p 16 -t 103000000 -e docx 46 | ``` 47 | 48 | ## zip_2MB.zip.PROM\[prometheushelp@mail.ch\] 49 | ``` 50 | ./prometheus_decrypt -i ./sample/zip_2MB.zip.PROM\[prometheushelp@mail.ch\] -o ./output/zip_2MB.zip -p 16 -t 103000000 -e zip 51 | ``` 52 | -------------------------------------------------------------------------------- /sample/file-example_PDF_500_kB.pdf.PROM[prometheushelp@mail.ch]: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/sample/file-example_PDF_500_kB.pdf.PROM[prometheushelp@mail.ch] -------------------------------------------------------------------------------- /sample/file-sample_500kB.docx.PROM[prometheushelp@mail.ch]: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/sample/file-sample_500kB.docx.PROM[prometheushelp@mail.ch] -------------------------------------------------------------------------------- /sample/file_example_AVI_480_750kB.avi.PROM[prometheushelp@mail.ch]: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/sample/file_example_AVI_480_750kB.avi.PROM[prometheushelp@mail.ch] -------------------------------------------------------------------------------- /sample/file_example_JPG_500kB.jpg.PROM[prometheushelp@mail.ch]: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/sample/file_example_JPG_500kB.jpg.PROM[prometheushelp@mail.ch] -------------------------------------------------------------------------------- /sample/file_example_MP4_480_1_5MG.mp4.PROM[prometheushelp@mail.ch]: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/sample/file_example_MP4_480_1_5MG.mp4.PROM[prometheushelp@mail.ch] -------------------------------------------------------------------------------- /sample/file_example_PPT_1MB.ppt.PROM[prometheushelp@mail.ch]: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/sample/file_example_PPT_1MB.ppt.PROM[prometheushelp@mail.ch] -------------------------------------------------------------------------------- /sample/file_example_XLSX_50.xlsx.PROM[prometheushelp@mail.ch]: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/sample/file_example_XLSX_50.xlsx.PROM[prometheushelp@mail.ch] -------------------------------------------------------------------------------- /sample/test.txt.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/sample/test.txt.enc -------------------------------------------------------------------------------- /sample/zip_2MB.zip.PROM[prometheushelp@mail.ch]: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cycraft-corp/Prometheus-Decryptor/cddf80d39ad2371fb71aed67c607aeeafa518aa4/sample/zip_2MB.zip.PROM[prometheushelp@mail.ch] -------------------------------------------------------------------------------- /winsup/winsup.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | /* 4 | MIT License 5 | 6 | Copyright (c) 2021 CyCraft Technology 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | */ 26 | 27 | package winsup 28 | 29 | import( 30 | "syscall" 31 | "log" 32 | ) 33 | 34 | func GetTickCount() int { 35 | kernel32, err := syscall.LoadLibrary("kernel32.dll") 36 | if err != nil { 37 | log.Fatal(err) 38 | } 39 | defer syscall.FreeLibrary(kernel32) 40 | 41 | kernel32GetTickCount, err := syscall.GetProcAddress(kernel32, "GetTickCount") 42 | if err != nil { 43 | log.Fatal(err) 44 | } 45 | 46 | tick, _, errno := syscall.Syscall(uintptr(kernel32GetTickCount), 0, 0, 0, 0) 47 | if errno != 0 { 48 | log.Fatal(err) 49 | } 50 | 51 | return int(tick) 52 | } 53 | -------------------------------------------------------------------------------- /winsup/winunsup.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | /* 4 | MIT License 5 | 6 | Copyright (c) 2021 CyCraft Technology 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | */ 26 | 27 | package winsup 28 | 29 | import( 30 | "log" 31 | ) 32 | 33 | func GetTickCount() int { 34 | log.Fatal("GetTickCount is only supported in Windows version.") 35 | return 0 36 | } 37 | --------------------------------------------------------------------------------