无管理员权限 LCU auth-token、port 获取(全网首发 go)

一: 提要:

参考项目:
https://github.com/Zzaphkiel/Seraphine

想做一个 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)
}
相关推荐
paopaokaka_luck22 分钟前
基于SpringBoot+Uniapp的健身饮食小程序(协同过滤算法、地图组件)
前端·javascript·vue.js·spring boot·后端·小程序·uni-app
Villiam_AY25 分钟前
Redis 缓存机制详解:原理、问题与最佳实践
开发语言·redis·后端
UQWRJ1 小时前
菜鸟教程R语言一二章阅读笔记
开发语言·笔记·r语言
岁忧2 小时前
macOS配置 GO语言环境
开发语言·macos·golang
朝朝又沐沐3 小时前
算法竞赛阶段二-数据结构(36)数据结构双向链表模拟实现
开发语言·数据结构·c++·算法·链表
魔尔助理顾问4 小时前
系统整理Python的循环语句和常用方法
开发语言·后端·python
Ares-Wang4 小时前
JavaScript》》JS》 Var、Let、Const 大总结
开发语言·前端·javascript
程序视点4 小时前
Java BigDecimal详解:小数精确计算、使用方法与常见问题解决方案
java·后端
你的人类朋友4 小时前
❤️‍🔥微服务的拆分策略
后端·微服务·架构
遇见尚硅谷5 小时前
C语言:*p++与p++有何区别
c语言·开发语言·笔记·学习·算法