问题描述
- 新人求教,我用mfc做了一个tcp fin的端口扫描器,死后得不出结果,求大神帮忙找出问题
- cpp文件
// scanDlg.cpp : implementation file
//#include ""stdafx.h""
#include ""scan.h""
#include ""scanDlg.h""
#include ""afxdialogex.h""#ifdef _DEBUG
#define new DEBUG_NEW
#endif// CAboutDlg dialog used for App About
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();// Dialog Data
enum { IDD = IDD_ABOUTBOX };protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}BEGIN_MESSAGE_MAP(CAboutDlg CDialogEx)
END_MESSAGE_MAP()// CscanDlg dialog
CscanDlg::CscanDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CscanDlg::IDD pParent)
m_star_port(_T(""""))
m_end_port(_T(""""))
m_IP(_T(""""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}void CscanDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX IDC_LIST1 m_list);
DDX_Text(pDX IDC_EDIT2 m_star_port);
DDX_Text(pDX IDC_EDIT3 m_end_port);
DDX_Text(pDX IDC_EDIT1 m_IP);
}BEGIN_MESSAGE_MAP(CscanDlg CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1 &CscanDlg::OnBnClickedButton1)
END_MESSAGE_MAP()// CscanDlg message handlers
BOOL CscanDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();// Add ""About..."" menu item to system menu.// IDM_ABOUTBOX must be in the system command range.ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){ BOOL bNameValid; CString strAboutMenu; bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); ASSERT(bNameValid); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING IDM_ABOUTBOX strAboutMenu); }}// Set the icon for this dialog. The framework does this automatically// when the application's main window is not a dialogSetIcon(m_hIcon TRUE); // Set big iconSetIcon(m_hIcon FALSE); // Set small icon// TODO: Add extra initialization herereturn TRUE; // return TRUE unless you set the focus to a control
}
hostent* CscanDlg::g_pHost = 0;
SOCKET CscanDlg::sock = 0;void CscanDlg::OnSysCommand(UINT nID LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID lParam);
}
}// If you add a minimize button to your dialog you will need the code below
// to draw the icon. For MFC applications using the document/view model
// this is automatically done for you by the framework.void CscanDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for paintingSendMessage(WM_ICONERASEBKGND reinterpret_cast<WPARAM>(dc.GetSafeHdc()) 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x y m_hIcon);}else{ CDialogEx::OnPaint();}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CscanDlg::OnQueryDragIcon()
{
return static_cast(m_hIcon);
}void CscanDlg::OnBnClickedButton1()
{
// TODO: Add your control notification handler code here
send_revc((LPSTR)(LPCTSTR)m_IP(LPSTR)(LPCTSTR)m_star_port(LPSTR)(LPCTSTR)m_end_port&m_list);//char ch1[]char tr1[]char tr2[]
}void CscanDlg ::send_revc(char ch1[]char tr1[]char tr2[]CListBox* m_list)
{
WSADATA WSAData;
WSAStartup(MAKEWORD(22) &WSAData);
sock=WSASocket(AF_INETSOCK_RAWIPPROTO_RAWNULL0WSA_FLAG_OVERLAPPED);//定义套接字
BOOL flag = true;
setsockopt(sockIPPROTO_IP IP_HDRINCL(char )&flagsizeof(flag));
char sLocalName[64];
gethostname((char)sLocalName sizeof(sLocalName)-1);
g_pHost = gethostbyname(sLocalName);
sockaddr_in addr_local;
addr_local.sin_addr = *(in_addr *)g_pHost->h_addr_list[0]; //绑定到本地网卡INADDR_ANY不行
addr_local.sin_family = AF_INET;//
addr_local.sin_port = htons(SOURCE_PORT);
bind(sock (PSOCKADDR)&addr_local sizeof(sockaddr_in));//绑套接字
DWORD dwValue = 1;
SADDR sAddr;
USHORT int1int2;
sAddr.m_destip=ch1;
sAddr.m_starpost=atoi(tr1);
sAddr.m_endpost=atoi(tr2);ioctlsocket(sock SIO_RCVALL &dwValue);int nTimeOut = 500;//设置超时setsockopt(sockSOL_SOCKET SO_SNDTIMEO (char*)&nTimeOut sizeof(nTimeOut));HANDLE threads[2];//开双线程threads[0] = CreateThread(NULL 0(LPTHREAD_START_ROUTINE)revcfunc(LPVOID)m_list0NULL);threads[1] = CreateThread(NULL 0(LPTHREAD_START_ROUTINE)sendfunc(LPVOID)(&sAddr) 0NULL);WaitForMultipleObjects(2threadsFALSEINFINITE);
}
USHORT CscanDlg ::checksumfunc(USHORT buffer int size)//检验和函数
{
unsigned long cksum=0;
while(size >1)
{
cksum+=*buffer++;
size -=sizeof(USHORT);
}
if(size)
{
cksum += *(UCHAR)buffer;
}cksum = (cksum >> 16) + (cksum & 0xffff);cksum += (cksum >>16);return (USHORT)(~cksum);}void CscanDlg ::sendfunc(SADDR* sAddr ){IP_HEADER ipHeader;TCP_HEADER tcpHeader;PSD_HEADER psdHeader;char Sendto_Buff[MAX_BUFF_LEN]; //发送缓冲区unsigned short check_Buff[MAX_BUFF_LEN]; //检验和缓冲区const char tcp_send_data[]={""This is my homework of networtI am happy!""};BOOL flag;int rectnTimeOver;//先试一下在外面弄好套接字初始化行不行flag=true;nTimeOver=1000; //填充IP首部ipHeader.h_verlen=(IPVER<<4 | sizeof(ipHeader)/sizeof(unsigned long));ipHeader.tos=(UCHAR)0;ipHeader.total_len=htons((unsigned short)sizeof(ipHeader)+sizeof(tcpHeader)+sizeof(tcp_send_data));ipHeader.ident=0; //16位标识ipHeader.frag_and_flags=0; //3位标志位ipHeader.ttl=128; //8位生存时间ipHeader.proto=IPPROTO_UDP; //协议类型ipHeader.checksum=0; //检验和暂时为0ipHeader.sourceIP=*(int*)g_pHost->h_addr_list[0]; //32位源IP地址可以直接获取ipHeader.destIP=inet_addr(sAddr->m_destip); //32位目的IP地址//计算IP头部检验和memset(check_Buff0MAX_BUFF_LEN);memcpy(check_Buff&ipHeadersizeof(IP_HEADER));ipHeader.checksum=checksumfunc(check_Buffsizeof(IP_HEADER));//构造TCP伪首部psdHeader.saddr=ipHeader.sourceIP;psdHeader.daddr=ipHeader.destIP;psdHeader.mbz=0;psdHeader.ptcl=ipHeader.proto;psdHeader.tcpl=htons(sizeof(TCP_HEADER)+sizeof(tcp_send_data));for(int i=sAddr->m_starpost;i<sAddr->m_endpost;i++)//填充TCP首部{tcpHeader.th_dport=htons(i); //16位目的端口号tcpHeader.th_sport=htons(SOURCE_PORT); //16位源端口号tcpHeader.th_seq=0; //SYN序列号tcpHeader.th_ack=0; //ACK序列号置为0//TCP长度和保留位tcpHeader.th_lenres=(sizeof(tcpHeader)/sizeof(unsigned long)<<4|0);tcpHeader.th_flag=1; //修改这里来实现不同的标志位探测,2是SYN,1是//FIN,16是ACK探测 等等tcpHeader.th_win=htons((unsigned short)16384); //窗口大小tcpHeader.th_urp=0; //偏移大小 tcpHeader.th_sum=0; //检验和暂时填为0//计算TCP校验和memset(check_Buff0MAX_BUFF_LEN);memcpy(check_Buff&psdHeadersizeof(psdHeader));memcpy(check_Buff+sizeof(psdHeader)&tcpHeadersizeof(tcpHeader));memcpy(check_Buff+sizeof(PSD_HEADER)+sizeof(TCP_HEADER)tcp_send_datasizeof(tcp_send_data));tcpHeader.th_sum=checksumfunc(check_Buffsizeof(PSD_HEADER)+sizeof(TCP_HEADER)+sizeof(tcp_send_data));//填充发送缓冲区memset(Sendto_Buff0MAX_BUFF_LEN);memcpy(Sendto_Buff&ipHeadersizeof(IP_HEADER));memcpy(Sendto_Buff+sizeof(IP_HEADER)&tcpHeadersizeof(TCP_HEADER));memcpy(Sendto_Buff+sizeof(IP_HEADER)+sizeof(TCP_HEADER)tcp_send_datasizeof(tcp_send_data));int datasize=sizeof(IP_HEADER)+sizeof(TCP_HEADER)+sizeof(tcp_send_data);//发送数据报的目的地址SOCKADDR_IN dest; memset(&dest0sizeof(dest));dest.sin_family=AF_INET;dest.sin_addr.s_addr=inet_addr(sAddr->m_destip);dest.sin_port=htons(i);rect=sendto(sockSendto_Buffdatasize 0(struct sockaddr*)&dest sizeof(dest));}}void CscanDlg ::revcfunc(CListBox* m_list){CString str;char RecvBuf[MAX_BUFF_LEN]; IP_HEADER* ip;TCP_HEADER* tcp; while(1)
{
int ret = recv(sock RecvBuf MAX_BUFF_LEN 0);
if (ret > 0)
{
ip = (IP_HEADER*)RecvBuf;
tcp = (TCP_HEADER*)(RecvBuf + (ip->h_verlen&0x0f)*4);
str.Format(_T(""%hu"") tcp->th_sport);
m_list->AddString(str);
}else str.Format(_T(""%d"")ret)m_list->AddString(str);
}
}头文件// scanDlg.h : header file
//#pragma once
#include
#include
#include
#pragma comment(libws2_32.lib"")
//#define SIO_RCVALL_WSAIOW(IOC_VENDOR1)
#include
#include
#include
#include ""afxwin.h""
#define IPVER 4 //IP协议预定
#define MAX_BUFF_LEN 65500 //发送缓冲区最大值
#define SIO_RCVALL _WSAIOW(IOC_VENDOR1)
#define SOURCE_PORT 8088 //local TCP segment source port
// CscanDlg dialog
class CscanDlg : public CDialogEx
{
// Construction
public:
CscanDlg(CWnd* pParent = NULL); // standard constructor// Dialog Data
enum { IDD = IDD_SCAN_DIALOG };
typedef struct ip_hdr //定义IP首部
{
UCHAR h_verlen; //4位首部长度4位IP版本号
UCHAR tos; //8位服务类型TOS
USHORT total_len; //16位总长度(字节)
USHORT ident; //16位标识
USHORT frag_and_flags; //3位标志位
UCHAR ttl; //8位生存时间 TTL
UCHAR proto; //8位协议 (TCP UDP 或其他)
USHORT checksum; //16位IP首部校验和
ULONG sourceIP; //32位源IP地址
ULONG destIP; //32位目的IP地址
}IP_HEADER;
typedef struct tsd_hdr //定义TCP伪首部
{
ULONG saddr; //源地址
ULONG daddr; //目的地址
UCHAR mbz; //没用
UCHAR ptcl; //协议类型
USHORT tcpl; //TCP长度
}PSD_HEADER;
typedef struct tcp_hdr //定义TCP首部
{
USHORT th_sport; //16位源端口
USHORT th_dport; //16位目的端口
ULONG th_seq; //32位序列号
ULONG th_ack; //32位确认号
UCHAR th_lenres; //4位首部长度/6位保留字
UCHAR th_flag; //6位标志位
USHORT th_win; //16位窗口大小
USHORT th_sum; //16位校验和
USHORT th_urp; //16位紧急数据偏移量
}TCP_HEADER;
typedef struct SADDR //定义TCP首部
{
char* m_destip;
USHORT m_starpost;
USHORT m_endpost;};
USHORT static checksumfunc(USHORT buffer int size);
void static sendfunc(SADDR sAddr);
void static revcfunc(CListBox* m_list);
void send_revc(char ch1[]char tr1[]char tr2[]CListBox* m_list);
SOCKET static sock; //用于收发TCP报文段的全局socket
hostent static *g_pHost;protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
HICON m_hIcon;// Generated message map functionsvirtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP()
public:
CListBox m_list;
afx_msg void OnBnClickedButton1();
CString m_star_port;
CString m_end_port;
CString m_IP;
};
解决方案
OnBnClickedButton1中的调用阻塞了消息循环。把send_revc中的waitForMultiObjects函数去掉吧,可以使用afxbeginthread()开启线程,并设置CWinThread类的成员变量m_bAutoDelete为TRUE。或者设置等待窗口,等待线程完成。反正WaitForMuliObjects阻塞了消息循环,所以在revc线程中添加ListBox条目会被阻塞。
解决方案二:
楼主给个程序吧 谢谢 我们期末答辩时候要用啊,楼主好人 752162305@qq.com
解决方案三:
楼主这个程序可以给我一份吗?这周答辩要用,460334480@qq.com
楼主好人,好人一生平安