一: 提要:
想做一个 lol 查战绩的软件,并且满足自己的需求(把混子和大爹都表示出来),做的第一步就是获取 lcu token ,网上清一色的使用 wmic 去查询的,这样也不是不行,不过需要使用管理员权限,恰好我在用Seraphine,发现别人根本不需要管理员权限就可以获取
但是我在全网并没有找到其他的实现,就自己研究了一下,发现谜底就在获取 token 的方式上。
二:获取过程:
shell
wmic PROCESS WHERE name='LeagueClientUx.exe' GET commandline
一般来说其他进程的详细数据是敏感信息,如果没有管理员权限,不能随便访问。如上述代码 wmic 只能有管理员才能访问,但是 commandline 又不是非常敏感的数据,
这里最后是通过 windows api进行交互,理论上说,大部分编译型语言都没问题,这里给到go的演示
go
package main
import (
"fmt"
"golang.org/x/sys/windows"
"log"
"os/exec"
"strconv"
"strings"
"unsafe"
)
func getProcessPidByName(name string) ([]int, error) {
cmd := exec.Command("wmic", "process", "where", fmt.Sprintf("name like '%%%s%%'", name), "get", "processid")
output, err := cmd.CombinedOutput()
if err != nil {
return nil, err
}
// 将输出按行分割
lines := strings.Split(string(output), "\n")
var pids []int
// 处理每行输出
for _, line := range lines {
trimmed := strings.TrimSpace(line)
if len(trimmed) > 0 {
// 转换为数字并添加到结果中
pid, err := strconv.Atoi(trimmed)
if err == nil {
pids = append(pids, pid)
}
}
}
return pids, nil
}
const (
ProcessCommandLineInformation = 60
PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
)
var (
modntdll = windows.NewLazySystemDLL("ntdll.dll")
procNtQueryInformationProcess = modntdll.NewProc("NtQueryInformationProcess")
)
type UNICODE_STRING struct {
Length uint16
MaximumLength uint16
Buffer *uint16
}
func GetProcessCommandLine(pid uint32) (string, error) {
// Open the process with PROCESS_QUERY_LIMITED_INFORMATION
handle, err := windows.OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, pid)
if err != nil {
return "", fmt.Errorf("failed to open process: %v", err)
}
defer windows.CloseHandle(handle)
// Query the buffer length for the command line information
var bufLen uint32
r1, _, err := procNtQueryInformationProcess.Call(
uintptr(handle),
uintptr(ProcessCommandLineInformation),
0,
0,
uintptr(unsafe.Pointer(&bufLen)),
)
// Allocate buffer to hold command line information
buffer := make([]byte, bufLen)
r1, _, err = procNtQueryInformationProcess.Call(
uintptr(handle),
uintptr(ProcessCommandLineInformation),
uintptr(unsafe.Pointer(&buffer[0])),
uintptr(bufLen),
uintptr(unsafe.Pointer(&bufLen)),
)
if r1 != 0 {
return "", fmt.Errorf("NtQueryInformationProcess failed, error code: %v", err)
}
// Check if the buffer length is valid and non-zero
if bufLen == 0 {
return "", fmt.Errorf("No command line found for process %d", pid)
}
// Parse the buffer into a UNICODE_STRING
ucs := (*UNICODE_STRING)(unsafe.Pointer(&buffer[0]))
cmdLine := windows.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(ucs.Buffer))[:ucs.Length/2])
return cmdLine, nil
}
func main() {
pids, _ := getProcessPidByName("LeagueClientUx.exe")
cmdLine, err := GetProcessCommandLine(uint32(pids[0]))
if err != nil {
log.Fatalf("无法获取进程命令行: %v", err)
}
fmt.Printf("进程命令行: %s\n", cmdLine)
}