go语言开发windows抓包工具

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

使用函数

syscall.WSAStartup

syscall.Socket

syscall.SockaddrInet4

syscall.WSAIoctl

syscall.WSARecv

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

Go 复制代码
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

Go 复制代码
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)
}
相关推荐
Swift社区2 小时前
在 Swift 中实现字符串分割问题:以字典中的单词构造句子
开发语言·ios·swift
没头脑的ht2 小时前
Swift内存访问冲突
开发语言·ios·swift
没头脑的ht2 小时前
Swift闭包的本质
开发语言·ios·swift
wjs20242 小时前
Swift 数组
开发语言
stm 学习ing3 小时前
FPGA 第十讲 避免latch的产生
c语言·开发语言·单片机·嵌入式硬件·fpga开发·fpga
湫ccc4 小时前
《Python基础》之字符串格式化输出
开发语言·python
mqiqe5 小时前
Python MySQL通过Binlog 获取变更记录 恢复数据
开发语言·python·mysql
AttackingLin5 小时前
2024强网杯--babyheap house of apple2解法
linux·开发语言·python