能力值:
( LV2,RANK:10 )
|
-
-
2 楼
如果能直接调用系统的ping命令实现也可以,可要怎样实现呢
|
能力值:
( LV7,RANK:100 )
|
-
-
3 楼
隐藏运行ping,创建进程时把输出输入用管道重定向,读管道数据即可
typedef struct _STARTUPINFOA {
DWORD cb;
LPSTR lpReserved;
LPSTR lpDesktop;
LPSTR lpTitle;
DWORD dwX;
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags;
WORD wShowWindow;
WORD cbReserved2;
LPBYTE lpReserved2;
HANDLE hStdInput;//here
HANDLE hStdOutput;//here
HANDLE hStdError;
} STARTUPINFOA, *LPSTARTUPINFOA;
直接用API也行,具体啥名字忘了,可以查到
|
能力值:
( LV7,RANK:100 )
|
-
-
4 楼
好像是用iphlpapi库里面的函数
看到里面有有一些导出函数是有关ICMP的
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
createpipe
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
ping效果不好 很多主机防ping 建议用半开扫描探测技术(syn刺探)
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
///////////////////////////////////////////
// ping.cpp文件
#include "../common/initsock.h"
#include "../common/protoinfo.h"
#include "../common/comm.h"
#include <stdio.h>
CInitSock theSock;
typedef struct icmp_hdr
{
unsigned char icmp_type; // 消息类型
unsigned char icmp_code; // 代码
unsigned short icmp_checksum; // 校验和
// 下面是回显头
unsigned short icmp_id; // 用来惟一标识此请求的ID号,通常设置为进程ID
unsigned short icmp_sequence; // 序列号
unsigned long icmp_timestamp; // 时间戳
} ICMP_HDR, *PICMP_HDR;
int main()
{
// 目的IP地址,即要Ping的IP地址
char szDestIp[] = "119.147.15.13"; // 127.0.0.1
// 创建原始套节字
SOCKET sRaw = ::socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
// 设置接收超时
SetTimeout(sRaw, 1000, TRUE);
// 设置目的地址
SOCKADDR_IN dest;
dest.sin_family = AF_INET;
dest.sin_port = htons(0);
dest.sin_addr.S_un.S_addr = inet_addr(szDestIp);
// 创建ICMP封包
char buff[sizeof(ICMP_HDR) + 32];
ICMP_HDR* pIcmp = (ICMP_HDR*)buff;
// 填写ICMP封包数据,请求一个ICMP回显
pIcmp->icmp_type = 8;
pIcmp->icmp_code = 0;
pIcmp->icmp_id = (USHORT)::GetCurrentProcessId();
pIcmp->icmp_checksum = 0;
pIcmp->icmp_sequence = 0;
// 填充数据部分,可以为任意
memset(&buff[sizeof(ICMP_HDR)], 'E', 32);
// 开始发送和接收ICMP封包
USHORT nSeq = 0;
char recvBuf[1024];
SOCKADDR_IN from;
int nLen = sizeof(from);
while(TRUE)
{
static int nCount = 0;
int nRet;
// ping次数
if(nCount++ == 1000)
break;
pIcmp->icmp_checksum = 0;
pIcmp->icmp_timestamp = ::GetTickCount();
pIcmp->icmp_sequence = nSeq++;
pIcmp->icmp_checksum = checksum((USHORT*)buff, sizeof(ICMP_HDR) + 32);
nRet = ::sendto(sRaw, buff, sizeof(ICMP_HDR) + 32, 0, (SOCKADDR *)&dest, sizeof(dest));
if(nRet == SOCKET_ERROR)
{
printf(" sendto() failed: %d /n", ::WSAGetLastError());
return -1;
}
nRet = ::recvfrom(sRaw, recvBuf, 1024, 0, (sockaddr*)&from, &nLen);
if(nRet == SOCKET_ERROR)
{
if(::WSAGetLastError() == WSAETIMEDOUT)
{
printf(" timed out/n");
continue;
}
printf(" recvfrom() failed: %d/n", ::WSAGetLastError());
return -1;
}
// 下面开始解析接收到的ICMP封包
int nTick = ::GetTickCount();
if(nRet < sizeof(IPHeader) + sizeof(ICMP_HDR))
{
printf(" Too few bytes from %s /n", ::inet_ntoa(from.sin_addr));
}
// 接收到的数据中包含IP头,IP头大小为20个字节,所以加20得到ICMP头
// (ICMP_HDR*)(recvBuf + sizeof(IPHeader));
ICMP_HDR* pRecvIcmp = (ICMP_HDR*)(recvBuf + 20);
if(pRecvIcmp->icmp_type != 0) // 回显
{
printf(" nonecho type %d recvd /n", pRecvIcmp->icmp_type);
return -1;
}
if(pRecvIcmp->icmp_id != ::GetCurrentProcessId())
{
printf(" someone else's packet! /n");
return -1;
}
printf("从 %s 返回 %d 字节:", inet_ntoa(from.sin_addr),nRet);
printf(" 数据包序列号 = %d. /t", pRecvIcmp->icmp_sequence);
printf(" 延时大小: %d ms", nTick - pRecvIcmp->icmp_timestamp);
printf(" /n");
// 每一秒发送一次就行了
::Sleep(1000);
}
return 0;
}
|
能力值:
( LV9,RANK:610 )
|
-
-
8 楼
Ping最简单,但是可能会被对方限制,代码也不用楼上那么麻烦
IcmpCreateFile/IcmpSendEcho/IcmpCloseHandle三个函数,不超过10行代码就可以搞定
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
谢谢,用这3个函数实现了
|