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)
}
相关推荐
csbysj202022 分钟前
Perl 格式化输出
开发语言
炒茄子22 分钟前
Windows:解决电脑开机解锁后黑屏但鼠标可见可移动的问题
windows·计算机外设
tao3556671 小时前
【Python刷力扣hot100】42. Trapping Rain Water
开发语言·python·leetcode
九江Mgx1 小时前
用 Go 手搓一个内网 DNS 服务器:从此告别 IP 地址,用域名畅游家庭网络!
golang·dns服务·内网dns
消失的旧时光-19431 小时前
Kotlin 协程最佳实践:用 CoroutineScope + SupervisorJob 替代 Timer,实现优雅周期任务调度
android·开发语言·kotlin
错把套路当深情1 小时前
Kotlin保留小数位的三种方法
开发语言·python·kotlin
赵谨言3 小时前
基于Python Web的大数据系统监控平台的设计与实现
大数据·开发语言·经验分享·python
专注前端30年3 小时前
Vue2 中 v-if 与 v-show 深度对比及实战指南
开发语言·前端·vue
星竹晨L4 小时前
C++继承机制:面向对象编程的基石
开发语言·c++
G_dou_4 小时前
Rust安装
开发语言·后端·rust