当前位置: 首页 > article >正文

go语言开发windows抓包工具

使用syscall调用window api, go有封装, 暂时不需要自己调用dll

使用函数

syscall.WSAStartup

syscall.Socket

syscall.SockaddrInet4

syscall.WSAIoctl

syscall.WSARecv

废话不多说, 上代码简洁明了使用方法

package main

import (
	"fmt"
	"net"
	"strconv"
	"strings"
	"syscall"
	"unsafe"

	"capture/console"
)

const (
	SIO_RCVALL uint32 = 0x98000001
)

const (
	SIO_RCVALL_ON uint32 = 0x00000001
)

func getLanIp() (string, error) {
	var ip string = ""

	addrs, _ := net.InterfaceAddrs()

	for _, addr := range addrs {
		// 检查是否为IP net
		ipNet, _ := addr.(*net.IPNet)
		if ipNet.IP.To4() != nil && ipNet.IP.IsGlobalUnicast() {
			ip = ipNet.IP.String()
			return ip, nil
		}
	}

	return ip, nil
}

func ipToIpBytes(ip string) [4]byte {
	ipStrArr := strings.Split(ip, ".")
	var ipBytes [4]byte
	for key, value := range ipStrArr {
		u64, _ := strconv.ParseUint(value, 10, 64)
		b := uint8(u64)
		ipBytes[key] = byte(b)
	}
	return ipBytes
}


func main() {
	var wsaData syscall.WSAData
	err := syscall.WSAStartup(0x0202, &wsaData)
	if err != nil {
		console.Log("WSAStartup:", err)
		return
	}

	var hints syscall.AddrinfoW
	hints.Family = syscall.AF_INET
	hints.Socktype = syscall.SOCK_RAW
	hints.Protocol = syscall.IPPROTO_IP

	rawSocket, err := syscall.Socket(int(hints.Family), int(hints.Socktype), int(hints.Protocol))
	if err != nil {
		console.Log("Socket:", err)
		return
	}

	ip, _ := getLanIp()
	addr := syscall.SockaddrInet4{
		Port: 0,
		Addr: ipToIpBytes(ip),
	}

	err = syscall.Bind(rawSocket, &addr)
	if err != nil {
		console.Log("Bind:", err)
		return
	}

	dwValue := SIO_RCVALL_ON
	dwValuePtr := unsafe.Pointer(&dwValue)
	dwValuePtrlen := uint32(unsafe.Sizeof(dwValue))

	dwOutValue := SIO_RCVALL_ON
	dwOutValuePtr := unsafe.Pointer(&dwOutValue)
	dwOutValuePtrlen := uint32(unsafe.Sizeof(dwOutValuePtr))

	var dwValueReturn uint32
	err = syscall.WSAIoctl(rawSocket, SIO_RCVALL, (*byte)(dwValuePtr), dwValuePtrlen, (*byte)(dwOutValuePtr), dwOutValuePtrlen, &dwValueReturn, nil, uintptr(0))
	if err != nil {
		console.Log("WSAIoctl: ", err)
		return
	}

	console.Log("成功启动")

	var buff [4096]byte
	wsabuf := syscall.WSABuf{
		Buf: (*byte)(unsafe.Pointer(&buff[0])),
		Len: uint32(len(buff)),
	}

	var ret uint32 = 0
	var flag uint32 = 0
	for {
		err = syscall.WSARecv(rawSocket, &wsabuf, 1, &ret, &flag, nil, nil)

		if err != nil {
			console.Log("WSARecv: ", err)
		}

		fmt.Printf("接收数据的长度: %d, 数据为: \n", ret)
		fmt.Printf("%v \n\n", buff[:ret])
	}

}

// WSAEINTR (10004): 系统中断错误
// WSAEBADF (10009): 文件描述符不正确
// WSAEACCES (10013): 权限被拒绝
// WSAEFAULT (10014): 内存访问错误
// WSAEINVAL (10022): 参数无效
// WSAEMFILE (10024): 打开的文件数量过多
// WSAEWOULDBLOCK (10035): 非阻塞socket操作现在无法完成
// WSAEINPROGRESS (10036): 进程中有一个阻塞的socket调用正在进行
// WSAEALREADY (10037): 操作已完成
// WSAENOTSOCK (10038): 描述符不是一个socket
// WSAEDESTADDRREQ (10039): 需要目标地址
// WSAEMSGSIZE (10040): 消息过长
// WSAEPROTOTYPE (10041): 协议类型错误
// WSAENOPROTOOPT (10042): 协议选项错误
// WSAEPROTONOSUPPORT (10043): 协议不支持
// WSAESOCKTNOSUPPORT (10044): socket类型不支持
// WSAEOPNOTSUPP (10045): 操作不支持
// WSAEPFNOSUPPORT (10046): 协议族不支持
// WSAEAFNOSUPPORT (10047): 地址族不支持
// WSAEADDRINUSE (10048): 地址已在使用中
// WSAEADDRNOTAVAIL (10049): 地址不可用
// WSAENETDOWN (10050): 网络下线
// WSAENETUNREACH (10051): 网络不可达
// WSAENETRESET (10052): 网络重置
// WSAECONNABORTED (10053): 连接中止
// WSAECONNRESET (10054): 连接重置
// WSAENOBUFS (10055): 无可用缓冲区
// WSAEISCONN (10056): 连接已经是连接状态
// WSAENOTCONN (10057): 连接未建立
// WSAESHUTDOWN (10058): 无法发送数据,socket被关闭
// WSAETOOMANYREFS (10059): 太多引用
// WSAETIMEDOUT (10060): 连接超时
// WSAECONNREFUSED (10061): 连接被拒绝
// WSAELOOP (10062): 有一个处理中的对话
// WSAENAMETOOLONG (10063): 地址名太长
// WSAEHOSTDOWN (10064): 主机宕机

capture是我的项目名字, console包是仿js的console

package console

import (
	"encoding/json"
	"fmt"
)

func Log(data ...interface{}) {
	bytes, err := json.MarshalIndent(data, "", "  ")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("%s\n", bytes)
}


http://www.kler.cn/a/303983.html

相关文章:

  • Nginx配置自带的stub状态实现活动监控指标
  • 平替 Spring 正当时!Solon v3.0.3 发布
  • 《云原生安全攻防》-- K8s安全防护思路
  • 超子物联网HAL库笔记:定时器[外部模式]篇
  • Ubuntu20.4系统编译瑞芯微RK3568 SDK
  • WPF中的ResizeMode
  • 在centos上搭建syslog服务端
  • 详情攻略来了!浏览网站记录怎么查?一文读懂这3种实用方法
  • Vue3 响应式工具函数isRef()、unref()、isReactive()、isReadonly()、isProxy()
  • 火焰检测算法、明烟明火检测、烟火检测算法
  • dirty pages , swapiness 查看SWAP占用进程
  • 线性代数 第六讲 特征值和特征向量_相似对角化_实对称矩阵_重点题型总结详细解析
  • 【原创】java+springboot+mysql疫情期间在线答疑系统设计与实现
  • Word使用手册
  • MDK keil STM32 局部变量不能查看值,显示为not in scope
  • 数业智能心大陆探索生成式AIGC创新前沿
  • Mysql JSON结果不能IN
  • ES基础知识
  • HarmonyOS学习(十二)——数据管理(一)分布式数据
  • 基于Ubuntu2404搭建mysql8配置远程访问
  • CAT1 DTU软硬件设计开源资料分析(TCP协议+GNSS定位版本 )
  • vue在一个组件引用其他组件
  • Docker Desktop 的安装与汉化指南
  • 【笔记】第二节 熔炼、轧制、热处理和焊接工艺
  • 供应RM500UCNAB-D10-SNADA模块
  • LLM的工作原理详解