2 a13479168897 a13479168897 于 2014.11.10 17:15 提问

新人求教,我用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 dialog
SetIcon(m_hIcon, TRUE);         // Set big icon
SetIcon(m_hIcon, FALSE);        // Set small icon

// TODO: Add extra initialization here

return 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 painting

    SendMessage(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(2,2), &WSAData);
sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED);//定义套接字
BOOL flag = true;
setsockopt(sock,IPPROTO_IP, IP_HDRINCL,(char )&flag,sizeof(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 int1,int2;
sAddr.m_destip=ch1;
sAddr.m_starpost=atoi(tr1);
sAddr.m_endpost=atoi(tr2);

ioctlsocket(sock, SIO_RCVALL, &dwValue);
int  nTimeOut = 500;//设置超时
setsockopt(sock,SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeOut, sizeof(nTimeOut));
HANDLE threads[2];//开双线程
threads[0] = CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE)revcfunc,(LPVOID)m_list,0,NULL);
threads[1] = CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE)sendfunc,(LPVOID)(&sAddr), 0,NULL);
WaitForMultipleObjects(2,threads,FALSE,INFINITE); 

}
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 networt,I am happy!"};
BOOL flag;
int rect,nTimeOver;
//先试一下在外面弄好套接字初始化行不行
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; //检验和暂时为0
ipHeader.sourceIP=*(int*)g_pHost->h_addr_list[0];  //32位源IP地址可以直接获取
ipHeader.destIP=inet_addr(sAddr->m_destip);    //32位目的IP地址

//计算IP头部检验和
memset(check_Buff,0,MAX_BUFF_LEN);
memcpy(check_Buff,&ipHeader,sizeof(IP_HEADER));
ipHeader.checksum=checksumfunc(check_Buff,sizeof(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_Buff,0,MAX_BUFF_LEN);
memcpy(check_Buff,&psdHeader,sizeof(psdHeader));
memcpy(check_Buff+sizeof(psdHeader),&tcpHeader,sizeof(tcpHeader));
memcpy(check_Buff+sizeof(PSD_HEADER)+sizeof(TCP_HEADER),
tcp_send_data,sizeof(tcp_send_data));
tcpHeader.th_sum=checksumfunc(check_Buff,sizeof(PSD_HEADER)+
sizeof(TCP_HEADER)+sizeof(tcp_send_data));

//填充发送缓冲区
memset(Sendto_Buff,0,MAX_BUFF_LEN);
memcpy(Sendto_Buff,&ipHeader,sizeof(IP_HEADER));
memcpy(Sendto_Buff+sizeof(IP_HEADER),&tcpHeader,
sizeof(TCP_HEADER));
memcpy(Sendto_Buff+sizeof(IP_HEADER)+sizeof(TCP_HEADER),
tcp_send_data,sizeof(tcp_send_data));
int datasize=sizeof(IP_HEADER)+sizeof(TCP_HEADER)+
sizeof(tcp_send_data);
//发送数据报的目的地址
SOCKADDR_IN dest;   
memset(&dest,0,sizeof(dest));
dest.sin_family=AF_INET;
dest.sin_addr.s_addr=inet_addr(sAddr->m_destip);
dest.sin_port=htons(i);
rect=sendto(sock,Sendto_Buff,datasize, 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(lib,"ws2_32.lib")
//#define SIO_RCVALL_WSAIOW(IOC_VENDOR,1)
#include
#include
#include
#include "afxwin.h"
#define IPVER 4 //IP协议预定
#define MAX_BUFF_LEN 65500 //发送缓冲区最大值
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
#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 functions
virtual 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;
};

3个回答

YoerShine
YoerShine   2014.11.10 23:57
已采纳

OnBnClickedButton1中的调用阻塞了消息循环。把send_revc中的waitForMultiObjects函数去掉吧,可以使用afxbeginthread()开启线程,并设置CWinThread类的成员变量m_bAutoDelete为TRUE。或者设置等待窗口,等待线程完成。反正WaitForMuliObjects阻塞了消息循环,所以在revc线程中添加ListBox条目会被阻塞。

a13479168897
a13479168897 前辈,能不能详细一点
大约 3 年之前 回复
baidu_15639641
baidu_15639641   2014.12.24 09:24

楼主给个程序吧 谢谢 我们期末答辩时候要用啊,楼主好人 752162305@qq.com

Shanchuntao
Shanchuntao   2016.01.04 21:37

楼主这个程序可以给我一份吗?这周答辩要用,460334480@qq.com
楼主好人,好人一生平安

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!