An example of a simple TCP Filter

zhaozj2021-02-11  156

An example of a simple TCP Filter

Source: Central Baiyun Huang BBS Author: huyuguang

These two days have gradually depressed, I have to take my own one of myself in the scalp, and very immature things. I have discussed this issue on the network. At that time, I proposed that IMD, 9X is the use of hook_device_service. One of these methods is that the receiving data is relatively low, directly got the MAC data, and you can know Which network card came up, and you can encrypt various data frames, IPX, and IP are not here. Because I have encountered encrypted environment and requirements, almost all require TCP encryption, in which case, if I do it on IMD, it is clear that IPX or ICMP's non-encrypted packets is efficient. Therefore, I used to consider making a filter on TCP, directly encrypting TCP data. Just on the site of Mark, a gadget is called TDIMON, the tool is very good, you can see the communication status of each process. It is a pity that 1. There is no source code, and the 2.free version cannot be obtained. With these two points, this tool can only be treated as a toy. At that time, I was more idle, I took a similar tool. About Filter, Art Baker's book is very detailed, I basically basically based on this book, do the TCP Filter, and the Filter of doing other devices, there is no difference, but the difference is because I don't know TCP is communicating with other devices (TDI CLINET), so you must look carefully to TDI specification. I will first describe some of the TCP / IP protocols in 2000 / NT. Under 2000 / NT, IP, TCP, UDP is implemented in a driver called TCP.SYS, which created 3 devices, which is IP, TCP, UDP. First describe DriveREntry. First of all, it is of course IOCREATEVICE, using file_device_unknown, because TCP devices are used by this parameter. Code is as follows: RtlInitUnicodeString (& usDeviceName, FILTER_NAME); status = IoCreateDevice (DriverObject, sizeof (DEVICE_EXTENSION), & usDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, & pDevObj); then obtain a pointer to call iogetdeviceobjectpointer tcp device.

Code is as follows: RtlInitUnicodeString (& usTargetName, TARGET_NAME); status = IoGetDeviceObjectPointer (& usTargetName, FILE_ALL_ACCESS, & pTargetFileObj, & pTargetDevObj); Note TARGET_NAME is case sensitive, I was #define TARGET_NAME L "// Device // Tcp", can not be written # Define target_name l "// device // TCP". Then we start calling oattachdevicetodeviestatck inserting into the TCP device. After the call is completed, we have to make our devices, like TCP, so all features are copied from TCPOBJ (PDEVOBJ-> XXX = PTCPOBJ-> XXX). Scan his TCPDRIVEROBJECT's MajorFunction, our Driver must support. Finally, DRIVERUNLOAD is set, because in order to facilitate debugging, we must write a unload. I have already told Driverentry, after DriveRentry, all IRPs that should be sent to TCP devices are now sent to our devices' handle, if something does not do, then you can send this IICALLDRIVER to send this IRP TCP devices let it process. Of course, we have to do something, so the code is as follows: UCHAR MajorFunction, MinorFunction; PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION) DeviceObject-> DeviceExtension; PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation (Irp); MajorFunction = pIrpStack-> MajorFunction; MinorFunction = pIrpStack-> Minorfunction; file: // dbgprint (...) PARSEIRP (IRP); IOCOPYCURRENTIRPSTACKLOCATIONTONEXT (IRP);

IOSETCOMPLETIONROUTINE (IRP, CompletionRoutine, Null, // Context True, // Invokeonse "; // Invokeonerror True); // Invokeoncancel Return IocallDriver (PDEVEXT-> TargetDevobj, IRP);

The code is very simple. In addition to Parseirp, others are routine. For the previous processing of TCP devices in this function. The function of the later process can be placed in the completionROUTION.

Ok, we have got all IRPs to the TCP device. This time our task is to understand how TCP devices work. Our task is to get TCP data and Accept TCP data from this machine. . Of course, the premise is that sending data through the TCP device, if some applications use Packet.sys, which use packet.sys, directly send TCP data directly, and the data does not pass the TCP device, and Filter has not been obtained. In order to learn how to get information from the IRP of the TCP device, first describe how the TDI Client is working with TCP communications and TDI Client. There are several examples in driverstdio. These examples are based on its own class libraries, but these examples are very powerful. One of the models of USB Web's thermometer makes me stunned. Because I also did the Driver of the PCI thermometer, but I never thought I can add a web server in it. Because the example in driverstdio is too complicated, I will be simply described here to give a small example. Because the sending process is simpler, first describe the send.

First call pIrp = TdiBuildInternalDeviceControlIrp (TDI_SEND_DATAGRAM, // sub function pDeviceObject, // pointer to device object pTransportObject, // pointer to udp object NULL, // pointer to event NULL); // pointer to return buffer assigned a irp, then call TdibuildsendDatagram (Pirp, // Pointer to IRP PDEviceObject, // Pointer To Device Object PTRANSPORTOBJECT, / / ​​POINTER TO File Object Null, // Completion Routine Null, // Completion Contex T PMDL, // Pointer to Data DBuffersize, // Size of Data PConnectInfo; // Connection Information Don't tell me, you should also know, the data is placed in a buf, calling this function, you must first build a MDL, put this BUF put it in. Then ... IRP is already good, as long as IOCALLDRIVER (Pudpobject, PIRP) is only used ... The UDP example (DataGram) is used, but TCP is the same, although the function is a bit different, but is also a TDibuildsend.

In order to figure out what the two functions above (what is what the IRP built in the end), there is no need to track, in fact, TDIBUILDXXX is just a macro, you can find it in tdikrnl.h. Open tdikrnl.h look, in each macro has found such a sentence: _IRPSP-> MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; so we know tdi client is through majorfunction = IRP_MJ_INTERNAL_DEVICE_CONTROL, minorfunction = send / recv / ... and tcp communication. This makes us confident that this method is feasible. (Not directly calling TDI functions, but issuing IRP) The process of receiving is more complicated (there are more choices for TDI Client, so I want to consider all situations), I saw such a macro in DDK Document: TDibuildReceive, I I want OK, like send, I think about it very simple, think that TDI Client has to accept data, it sendses an IRP to the TCP, then return to Pending, when there is data, TCP processing this IRP, then TDI Client Just handle the obtained data in this IRP IRP_COMPLETE. This is indeed a choice of TDI Client, but when I tried, I found that at least WSOCK didn't do this, because I opened an IE, browsed a web page, but I found that the data I sent is very good. However, the received data is not, and in fact, TCP does not seem to be used by minorfunction = TDI_RECEIVE IRP. I have worked hard for a while later, and later I read DDK Document, I found that the TDI Client also has the second choice. First, send a IRP, minorfunction = TDI_SETHANDLER to TCP, set some callback functions, and then happen When TCP calls these callback functions, these function names are ClientEventXXX. This process can take a closer look at DDK Document, see TDIBUILDSETEVENTHANDLER, know which procedures can be used. Receive is also one of them, so our approach has been obtained. First we get an IRP. If it is set_eventhandler, then modify the entrance to the callback function set to the TCP, point it to our own written function, and retain the original entrance, then call in our own written function it.

转载请注明原文地址:https://www.9cbs.com/read-6082.html

New Post(0)