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)
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值