The bottom-level packet in Windows is sent in combat

Source: Internet
Author: User

1. Introduction

The so-called "underlying packet" refers to the "run" at the data link layer of the packet, simply said "Ethernet frame", and our common socket can only send "run" in the transport layer of TCP, UDP and other packets, these transport layer packets have been able to meet most of the demand, However, there are times when you need to send the underlying packet (such as a SYN scan), so how do I send it?

This document describes some of the problems and solutions that I have encountered in my attempt to achieve this, and it is important to note that: ① This article only considers implementations on Windows ② The main purpose of this article is to implement the sending section ③ this article assumes that the reader understands the network hierarchy and some basic network programming methods ④ This article is just talking about conventional techniques, Never be used for unlawful purposes.

2. A simple method for sending the underlying packetA) Raw Socket

Raw sockets are the easiest way to implement the underlying (network layer) packet, and you can use SOCK_RAW to set the socket type to raw when you create a socket using wsasoccket (or socket):

Socket = Wsasoccket (Af_inet,sock_raw,ipproto_ip,null,0,0)// Create an original socket

The original socket using Ipproto_raw initialization can send and receive the network layer packets, the sending of a TCP packet need to construct the IP header, TCP header, content and each checksum, after constructing the packet, use the SendTo method to send the packet (note, The destination IP address is already included in the manually constructed IP header, so the destination address parameter of the sendto is meaningless. Raw sockets are very handy, and the socket () function under other platforms has similar functionality. So is it possible to use raw sockets to achieve the goal? The answer is in the negative.

Starting with Windows XP SP2, the future operating system (in addition to some server systems), for security reasons, Microsoft has imposed several limitations on raw sockets [3], the main limitations are as follows:

A) The TCP packet cannot be sent using the raw socket. (? Д?)!?

b) The raw socket cannot be used to send UDP packets with incorrect source IP address. (meaning that it cannot be used to forge the source address)

c) the bind () function cannot be raised on a raw socket of type IPPROTO_TCP.

With the limitations, the RAW socket has limited functionality, but there are several ways to continue using it:

① Manual modification of Tcpip.sys, using the idea of cracker, the so-called "limit" reflected in the code, is a few if statements, and then reflected on the PE file, it is some jz\jne and other directives, Then modifying the specific bytes of Tcpip.sys can lift these limits, a method that has been implemented very early, albeit subtly, but with obvious drawbacks.

② uses a virtual machine that contains a previous system of Windows XP SP2, which is theoretically feasible, but at the expense of efficiency and convenience.

So is there any other way?

B) Winpcap

WinPcap is a "library" consisting of multiple components (dynamic link library + driver) and related SDKs. It can provide the ability to listen to the underlying packet and send the underlying packet, but be aware that WinPcap does not provide the underlying packet filtering capabilities, so it cannot be used as a firewall. The use of WinPcap is very simple, and the code for sending an Ethernet frame is as follows:

1#include <stdlib.h>2#include <stdio.h>3 4#include <pcap.h>5 6 voidMainintargcChar**argv)7 {8pcap_t *FP;9     CharErrbuf[pcap_errbuf_size];TenU_char packet[ -]; One  A     /*turn on the output device*/ -     if(fp = Pcap_open (argv[1],//Device Name -          -,//the part to capture (captures only the first 100 bytes) thePcap_openflag_promiscuous,//Promiscuous Mode -          +,//Read timeout time -Null//Remote machine Verification -Errbuf//Error Buffering +)) ==NULL) -     { +fprintf (stderr,"\nunable to open the adapter.%s are not supported by winpcap\n", argv[1]); A         return; at     } -     /* - padding Packet content code is omitted here: Populate Ethernet frame header, IP first -     */ -      -     /*sending a packet*/ in     if(Pcap_sendpacket (FP, packet, - /*size*/) !=0) -     { tofprintf (stderr,"\nerror sending the packet: \ n", Pcap_geterr (FP)); +         return; -     } the     return; *}

The above code sends an Ethernet frame, which can be divided into three steps: Open the WINPCAP device (handle/descriptor?). ), manually construct an underlying packet, send! The whole process has no extra action and is very simple. So how is WinPcap implemented?

The image on the left is an architecture diagram from WinPcap Official document, WinPcap is a NPF (netgroup Packet filter, network packet filtering) driver, which is an NDIS middleware driver, all packets passing through the network card will "pass" the driver, When receiving a passing packet, NPF can choose to just count the package or write to the file (for traffic monitoring), or write to a ring buffer, Then the user-state program calls Wpcap.dll some functions, using WINAPI and driver interaction, to obtain the data in the drive buffer, the purpose of monitoring the underlying packet is achieved. As for sending the packet, the user-state program calls WinPcap's SDK functions, these functions call the DLL method, the DLL and the API and NPF communication, NPF is the lowest layer of the driver, but it is not responsible for direct data transmission, NPF and then call the lower level of the network card driver to implement the packet delivery.

It is important to note that the packet filtering section of the NPF in WinPcap is interesting, based on the BSD Packet filter (BPF), a scheme that enables extremely efficient data filtering, in BPF, A complex filtering (matching) rule is transformed into a regular symbol string (or BPF program), which is then filtered without calculating the original filtering rules, but instead feeds the data into a state machine controlled by a regular symbolic string that can be represented by a state machine, which is further optimized in NPF. , the matching rules are converted into symbolic strings to regenerate into machine codes. Filter rules are given by the user-state program, before the incoming driver, wpcap.dll it into the BPF program, NPF received, before it is called to filter the machine code, and then call the converted "Filter function" to match the underlying packet, in pursuit of high efficiency.

WinPcap using the NDIS driver to listen and send the underlying packets is a good solution, saying that the software on Windows has no control over the network devices. But what if we don't want to use a third-party tool like this? Or do you want to do some of your own processing when sending and receiving, filtering the underlying package, or even more complex logic in the drive layer? If so, the use of WinPcap is not enough, we need to write a driver to complete this task.

3. Low-level packet sending based on NDIS Protocol driver

"All problems in computer science can is solved by another level of indirection." The network operation under Windows also follows the above sentence, and a simple operation will be passed between several levels , until it's really done at the bottom.

The diagram on the right shows the general call hierarchy when calling the socket operation, where the orange part (Top 2 layer) is the user state, the blue part (the middle 4 layer) is the driver of the kernel state, and the lowest layer is the NIC hardware.

The AfD driver is a drive level of an undisclosed interface (part of the system), called by Winsock, and many of this knowledge originates from the source code analysis of ReactOS, and references [7] do a good job of explaining the topic. The TDI (Transport Driver Interface) is the Transport Layer driver interface, which is called by the AfD to implement the Transport layer logic and connect with the upper program, some firewalls and most traffic monitoring software are based on the TDI layer, where the advantage is in monitoring, While intercepting and executing network behavior, the relevant process information can still be obtained. The TDI hierarchy is relatively low, and if the program calls the layer for network operation directly, then the firewall and monitoring program based on the above level of TDI will not be detected. In addition, in Microsoft's documentation, the TDI layer is a technology that is labeled as being deprecated, and the literature [8] describes the technology as a whole. TDI is still not the lowest-level driver, under the TDI is the NDIS layer, which consists of three sub-layers, the NDIS protocol driver (e.g. TCP/IP stack driver tcpip.sys), NDIS Middle-tier driver, NDIS miniport driver, The miniport driver is responsible for working directly with the NIC driver, and then the hardware part, but until the hardware level network operation is actually executed. It's a bit surprising that a socket operation has to go across so many levels of abstraction, but each layer should have its own rationale, limited to the ability to do this here.

Back to the purpose of this article: send the underlying packet. To achieve this, our program cannot use the call method of the right graph, just like the WinPcap NPF driver, we should call the NDIS layer directly from the application layer across the intermediate layers.

This paper uses the mode of writing the NDIS protocol Driver + Application layer direct call, but this article will not explain the specific details of NDIS layer driver, the reference [6] is very good to the basic principle. (Refer to the WDK documentation for new content) in fact, only need to understand the approximate structure, do not need to know too much details of the NDIS layer can be "written" to achieve the purpose of this article driver! The sample code for the WDK (Windows Driver Kit) contains a project called Ndisprot, which has implemented one of the most basic non-connected NDIS protocol drivers and supports receiving/sending Ethernet frames.

Below, please see the documentation under the Ndisprot Engineering catalogue:

"This sample demonstrates a Connection-less NDIS 6.0 protocol. The driver supports sending and receiving raw Ethernet frames using readfile/writefile calls from User-mode. It is receives frames with a specific ethertype field. As an NDIS protocol ... "

It can be seen that this sample drive is basically in line with our requirements, in addition, the project also comes with the test program Prottest.exe, that is, the user-state program in the documentation, since there is such a convenient resource, the following need to do is to modify it slightly, and then compile and run!

4. Hello "NDIS Protocol Driver"

STEP1 [Installing the WDK Environment]

My installation environment is: Windows 8.1 x64 + Visual Studio 2013, first download Windows Driver Kit 8.1 update1,visual Studio 2012/2013 can be automatically integrated with WDK 8.1, provided that Install vs before installing the WDK. Open VS2013 after installation can see "Windows Driver" appears in the installed template, indicating that the environment has been well-equipped, is not very convenient.

STEP2 [Modify & Compile Ndisprot project]

Download the sample code from here, unzip and find the project folder NDIS connection-less Protocol Driver Sample, open solution\sys\630\ndisprot630.vcxproj

First select the appropriate compilation configuration and platform, set the platform toolset to "WindowsKernelModeDriver8.1", and then recompile by confirmation:

Open the ndisprot630 project properties again, and you can see that there are more property pages on the left. Open the VC + + Directory property Page "x86" to "x64". Open the property page c/c++-> Advanced, check whether the calling convention is set to __stdcall, and leave the remaining settings essentially the default.

Open the Driver Signing->general property page, sign mode select "Test Signs", Test Certificate Select "Create Test Certificate" for creating a new test signature

The Settings section is here, and here are some changes to the sample code:

Comment out 122-135 lines in the Send.c file

        //If (pethheader->ethtype! = globals.ethtype) //Check the Ethernet frame type and stop sending if not for 0x8e88 //{        //DEBUGP (Dl_warn, ("Write:failing Send with Ethtype%x\n",//pethheader->ethtype)); //NtStatus = Status_invalid_parameter; //Break ; //}        //if (! NPROT_MEM_CMP (Pethheader->srcaddr, popencontext->currentaddress, Nprot_mac_addr_len))//{ //check Ethernet frame source MAC address, not real address stop sending //DEBUGP (Dl_warn, ("Write:failing with invalid Source address")); //NtStatus = Status_invalid_parameter; //Break ; //}

Comment out the No. 238 line in the SEND.C file

    //    sendflags |= Ndis_send_flags_check_for_loopback; //Set send flag, generate loopback receive packet after send        ndissendnetbufferlists (                              popencontext,bindinghandle,                      pnetbufferlist,                      ndis_ Default_port_number,                      sendflags);

Comment out the No. 539, 544 lines in the Recv.c file

if(Pethheader->ethtype = =Nprot_8021p_tag_type) {USHORT UNALIGNED*Pethtype; if(Bufferlength < (sizeof(Ndisprot_eth_header) +4))    {         Break; } Pethtype= (USHORT UNALIGNED *) ((Puchar) &pethheader->ethtype +4); if(*pethtype! =globals.ethtype) {//Break ; stop receiving if the Ethernet frame type is not equal to 0x8e88     }}Else if(Pethheader->ethtype! =Globals.ethtype) {    //Break ;}

After the modification is finished, the following files are generated after compiling:

Ndisprot630.cer ... Digital signature of the driver

Ndisprot630.inf ... Driver information (for installation)

Ndisprot630.sys ... Driver Program

View the details of the digital signature in the Sys file's properties, and if the digital signature shows "This digital signature is OK", the driver is signed correctly and can be installed. If not, install the CER certificate file and import the certificate to Trusted root certification authorities. (Effective after reboot) in addition, if the driver fails to start in subsequent installations, it is mostly because the signature is invalid, and after Win7 64 bits, Microsoft prohibits the driver with an invalid digital signature from running (but can be installed). In addition to testing signatures, it is also possible to use specialized signature tools for driver signatures, such as the "Drive-to-network signature tool," which is handy for signing with these tools, but has a limited number of times for unpaid editions.

STEP3 [Installation & operation]

First start the test mode of Windows, with administrator privileges to execute the command "Bcdedit/set testsigning on", after restarting the desktop in the lower right corner of the "Test Mode" tab, the command in the switch to off to turn off the test mode. The second step requires the driver to be forced to sign: (Windows8.1 64-bit only)

After clicking "Restart Now", press F7 to select "Disable Driver Signing" after the system restarts. After rebooting, you can install the driver that you just compiled, the steps are as follows: After opening the network adapter properties, click "Install", select "Protocol" installation, then select "Install from Disk", then select the INF ready to install, if there is an unsigned warning installed, choose to continue the installation.
The "Sample NDIS Protocol Driver" entry appears in the protocol for all adapters after installation, indicating that the driver has already been installed, and then executes the "net start Ndisprot" command with the administrator, if "the sample NDIS The Protocol driver service was successfully started. "Indicates that the drive has run successfully.

Open \solution\test\prottest.vcxproj, this is the test program in sample, after generating Prottest.exe, execute "prottest.exe-e", if the driver installed and run successfully, you should be able to see the list of network interface card. Through the analysis of the Prottest code, the entire operation process mainly uses the following functions:Createfilea(open driver handle),DeviceIoControl(send a specific control word to the driver, such as Ioctl_ Ndisprot_open_device Open the specified network adapter),WriteFile(send Ethernet frame), and so on.

Based on this sample project, it is easy to implement the user-state program control driver for the underlying packet delivery (including, of course, receive) This is limited to the length of the details are not posted here. (for example, how to construct a TCP packet, how to send, etc., I would like to write a special essay description) after the actual test found that the use of this way to send packet efficiency and high, the main reason is that the sending and receiving process still involves the user state and the kernel state switch, if you want to achieve the maximum efficiency of the network card, More complex logic must be implemented at the drive level.

---by Shenck

Reference documents:

[Raw socket programming under 1]:windows 2000 | Http://www.cnblogs.com/painmoth/articles/137819.html

[2]:raw Socket Programming Cases Urealyticum | Http://blog.chinaunix.net/uid-21237130-id-159816.html

[3]:MSDN document TCP/IP Raw sockets| Http://msdn.microsoft.com/en-us/library/ms740548.aspx

[4]:winpcap Official Technical Document (Chinese version) | Http://www.ferrisxu.com/WinPcap/html/main.html

[5]:NPF Drive Core Guide | Http://www.cnblogs.com/coolzgx/archive/2010/01/23/1654537.html

[6]: PassThru-based NDIS middle-tier Driver extension | Http://www.xfocus.net/articles/200605/865.html

(Anti-Hang reprint address: http://www.cnblogs.com/dubingsky/archive/2009/08/20/1550910.html)

[7]: from socket API to TDI driver | http://bbs.pediy.com/showthread.php?t=144493

[8]:tdi Overview @CodeMachine | Http://codemachine.com/article_tdi.html

The bottom-level packet in Windows is sent in combat

Contact Us

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.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.