After I wrote a simple SPI firewall program (only using IP filtering, but not packet filtering), I gave up research on SPI, however, a friend recently asked about the implementation of the SPI firewall, and now I will make a detailed analysis and summary of the SPI. First, let's take a look at the general implementation method of the firewall. The first is the TCP/IP structure (osi7 Layer Model)
---
| Application Layer | -- exe program, such as IE
---
| Presentation layer | --- ws2_32.dll
---
| Session Layer | --- SPI
---
| Transport layer | --- TDI (data of ICMP and other protocols cannot be intercepted)
---
| Network Layer | --- NDIS (can intercept all network data)
---
| Link layer | --- Device Driver
---
| Physical layer | --- Nic
---
From the above we can clearly see that we have a variety of ways to implement the firewall, such as using the hook api to hook the winsocket API function in the presentation layer, and using the standard SPI method provided by windows at the Session Layer, the SPI is more standardized than the hook api method and more powerful, but it is still in the user model ,. On the transport layer, you can write the driver to implement the firewall. Although the kernel model has been reached, the data of the protocols such as ICMP cannot be filtered like the above two methods, because the data of ICMP and other protocols does not pass through the transmission layer. In this way, we can see that in windows, the most standard, the most standard, and the most powerful way to implement the Firewall should be in NDIS (that is, the network layer), because NDIS provides some rules, as long as we call some well-written functions to organize data, the functions are not only powerful, but also simple to the device drivers at the link layer below. It should be said that firewalls can also be implemented at the link layer, however, it seems unnecessary and complicated. Now let's look at the SPI structure.
-------
| Ws2_32.dll |
-------
| SPI |
-------
| SPI | --- there can be many layers, that is, the so-called hierarchical service provider.
-------
| Basic service provider |
------- There are two types of service providers: one is a hierarchical service provider and the other is a basic service provider. The figure above is not very accurate. We can understand this as follows, the layer-based service provider we write must call the basic service provider or the layer-based server provider at the following layer, and then submit the request to the layer above it (the layer above may be another layer-based service provider, or ws2_32.dll ). The basic service provider we write must call the system basic service provider and submit the request to ws2_32.dll. Note that the system may not only install our basic service provider, but also the basic service provider written by others. When multiple layered service providers and multiple basic service providers are installed, the two are organized differently.
For example
---------------------
| Ws2_32.dll |
---------------------
|
------- |
| Another Layered Service Provider |
------- |
|
------- |
| Another Layered Service Provider |
-------- |
|
------- |
| Our Layered Service Provider |
-------- |
|
--------------------
| Layered service provider of others | basic service provider of others | our basic service provider |
-----------------------
|
----------------------
| Basic System Service Provider |
-------------------------------- If you still don't understand the figure above, I can't help it. From the above, we can see that the organizational philosophy of this SPI is stratified. However, the number of layers of basic service providers is less than that of hierarchical service providers. Theoretically, hierarchical service providers can have N layers (I don't know if n is unlimited) how are these layers organized? Connect them through a function. This function is
Wspstartup
Below is his prototype
Int wspstartup (
Word wversionrequested,
Lpwspdataw lpwspdata,
Lpwsaprotocol_infow lpprotocolinfo,
Wspupcalltable upcalltable,
Lpwspproc_table lpproctable
); What is important here is that the third parameter lpprotocolinfo and the last parameter lpproctable, and lpprotocolinfo are left for later. This is related to the installation of the service provider. Now let's look at the API in ws2_32.dll, most of the APIs in ws2_32 are finally mapped to 30 functions in SPI after being called by the application. These 30 functions start with WSP. Note: The 30 functions in SPI cannot be directly called by the application, but should be called by ws2_32.dll. Lpwspproc_table is a table that stores pointers to these 30 functions. We call the wspstarup of the service provider at the next layer to obtain the 30 function pointers of the service provider at the next layer. At the same time, we also need the Export (SPI is a DLL) function, so that the service provider at the previous layer can call these 30 function pointers. For example
Int wspstartup (
Word wversionrequested,
Lpwspdataw lpwspdata,
Lpwsaprotocol_infow lpprotocolinfo,
Wspupcalltable upcalltable,
Lpwspproc_table lpproctable
)
{
Lpwspstarup wspstarproc = getprocaddress (lbhandle, "wspstartup"); // obtain the wspstatrup function pointer of the service provider at the next layer. Remember to loadlibrary the DLL of the service provider at the next layer.
// Remember to keep the original function pointer of the next layer. Anyone with hook api experience should know, just like the original address of your hook api. wspproc_table systemproc = * lpproctable; // then you can set your own processing function, which is similar to hook api, for example
Lpproctable-> lpwspsend = wspsend; return 1;
} Then we implement our own wspsendint wspsend (
Socket s,
Lpwsabuf lpbuffers,
DWORD dwbuffercount,
Lpdword lpnumberofbytessent,
DWORD dwflags,
Lpwsaoverlapped lpoverlapped,
Lpwsaoverlapped_completion_routine lpcompletionroutine,
Lpwsathreadid lpthreadid,
Lpint lperrno
)
{
/* ++
Here, we can use functions such as getsockname and the first parameter to obtain the socket port and IP, and buffer can be processed here, all IP address filtering packages can be implemented, and then the corresponding functions of the service provider at the next layer are called and
-*/
Return systemproc. lpwspsend (S, lpbuffers, dwbuffercount, lpnumberofbytessent, dwflags, lpoverlapped, lpcompletionroutine, lpthreaid, lperrno );
} Of course, the specific implementation is not so simple. For complicated I/O models and overlapping requests in winsocket, callback functions should also be written. We will not discuss these issues now, if you are interested in searching for information, you can also use the sniffer function to analyze the data that you are interested in lpwsabuf lpbuffers in network protocols such as POP3 and telnet, the following structure is provided in this parameter.
Do you know how to parse the package?
Typedef struct _ wsabuf {
U_long Len;
Char far * Buf;
} Wsabuf, far * lpwsabuf ;------
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.