Interface I'm going to finish this. Communication protocol resolution Besides, I always think I'm in the same nonsense. Here I also give myself these two days of the agreement resolution find a network storage to do a backup.
GH0ST Communication Protocol Resolution (1)
The so-called snake hit seven inches, today we have a complete analysis of GH0ST communication protocol, see GH0ST This remote control of the core technology in the ins and outs.
*******************************************************************************
Starting the IOCP server initialization from the main terminal
The IOCP server is called in the Cgh0stapp::initinstance function, and is actually called a member function of CMainFrame: cmainframe::active. Let's see what this function does.
First determine if the M_iocpserver global variable has been pointed to a ciocpserver, if so, it is necessary to close it, and delete the memory space of this ciocpserver. I'm a little hesitant to follow this ciocpserver::shutdown function, on the one hand, if we go to trace, we will have to go deep into the Ciocpserver class to cobwebs, looking for shutdown function, and a series of functions called inside this function, so I have to go deep through the entire calling process. On the other hand, if tracking it, will make the main line of this article messy, if not tracking it, I will be messy, after thinking, rather let everyone crazy, also can't let me crazy, because I lost my mind to write this analysis article ...
Okay, let's take a look at this ciocpserver::shutdown. An execution logic inside this function.
Let's take a look at this ciocpserver::m_binit variable. What does this variable do, look at these places:
1: There is a sentence in the Ciocpsserver constructor: M_binit = false;
2: In ciocpserver::initialize This function has such a sentence: M_binit = true;
3: In Ciocpserver::shutdown This function has such a sentence: M_binit = false;
4: In ciocpserver::isrunning This function has such a sentence: return m_binit;
From each of these places we can know that this m_binit is a record ciocpserver this server running state, it has only two meaning: open or close. This value will be set to True when the Ciocpserver server is initialized. This value will be set to False when it is closed, and this value should be used as a consideration for the ciocpserver running state at other times.
First judge whether this m_binit is false, if false that the Ciocpserver itself does not open, but also to turn off a fart, if true, then set its running state to false.
Then look at the Ciocpserver::m_btimetokill variable. The role of this variable:
1: There is a sentence in the Ciocpsserver constructor: M_btimetokill = false;
2: In Ciocpserver::shutdown This function has such a sentence: M_btimetokill = true;
3: There is a sentence in the core completion port loop:
for (BOOL bstayinpool = TRUE; Bstayinpool && Pthis->m_btimetokill = = false;)
As can be seen, M_btimetokill this value is a record whether to end the completion port of all waiting threads of such a sentinel value, if the value is set to True, then all the threads waiting on the completion port will end and exit, so that There will be no more worker threads to handle all read, Write, initize requests on this completion port, and here's one thing to understand: the number of worker threads is related to the number of cores on the machine running the console.
Next, the process of our program to ciocpsserver::stop this function, one of the main function of this function is to end the listening socket, has reached the subsequent connection request is no longer entertained. Let's see what Ciocpserver has done in this function:
First, let's look at the purpose of this ciocpserver::m_hkillevent variable.
1: There is such a sentence in the Ciocpserver constructor
M_hkillevent = CreateEvent (null, TRUE, FALSE, null), an artificial confidence is created in the constructor, the initial state is an untrusted, unnamed event object.
2: In Ciocpserver::listenthreadproc This function has such a sentence called
if (WaitForSingleObject (pthis->m_hkillevent, +) = = Wait_object_0)
Break
In the infinite loop in the thread that listens to the line, the function of this sentence is that when m_hkillevent is trusted, this infinite loop ends
3: In a critical place, is the invocation of SetEvent (m_hkillevent) in Ciocpserver::stop.
From the above analysis, we can see that the meaning of this variable exists, is to be able to shut down the Ciocpserver this server, so that the listener thread end monitoring such a function.
Let's take a look at the purpose of this ciocpserver::m_hthread variable.
1: In the Ciocpserver::initialize function, the following call is
M_hthread = (HANDLE) _beginthreadex (NULL,//Security
0, //Stack size-use default
Listenthreadproc,//Thread FN entry point
(void*) This,
0, //Init flag
&dwthreadid); Thread Address
2: In Ciocpserver::stop, there is a call to WaitForSingleObject (M_hthread, INFINITE).
From the above analysis we can see that this variable is useful as a listener thread of a handle to exist, it represents the listener thread entity.
At this point, this ciocpserver::stop function we have analyzed, back to the Ciocpserver::shutdown function continue to see.
First, let's look at the variable Ciocpserver::m_soclisten
1: In Ciocpserver::initialize This function, is assigned to listen to the socket handle, and is set to only the network event fd_accept interested, then is tied to the machine, began to listen. Here I would like to mention that this listener socket is not associated with the subsequent creation of the completion port, which is associated to the completion of those sockets that have established connections to the host terminal. If any network events occur on these sockets, the message dispatch function on the completion port is completed.
About the completion of the port operation mechanism, here is not the table, there will be a detailed introduction, here only one point, this is about the completion of the port of the general architectural problems: Create a completion port + set a dedicated to the completion of the port service n threads, and constantly go to query the completion port on whether there are read, write these requests + Multiple actions to post read or write requests to this completion port + Real to handle these read and write requests. The above is an approximate completion port execution condition.
2: In Ciocpserver::listenthreadproc this listener thread, there is the following action
int nret = wsaenumnetworkevents (Pthis->m_soclisten,
Pthis->m_hevent,
&events);
Choose a network event that is of interest to us from the network event that occurs on the m_socklisten socket, as we have previously registered a network event of interest on M_socklisten, that is, fd_accept. So here we are only dealing with this network event that occurs on this socket.
3: In ciocpserver::onaccept This function, there is the following action
Clientsocket = Accept (M_soclisten,
(LPSOCKADDR) &sockaddr,
&nlen);
In this case, the connection request that occurs on this socket is treated as one of the accepted connections.
From the above analysis, we can draw a conclusion that this m_soclisten is a listener socket handle.
Next, we make an analysis of the ciocpserver::m_hevent variable
1: In the Ciocpserver::initialize function, this variable is done in the following operation
M_hevent = Wsacreateevent ();
An assignment was made to create an automatically reset, untrusted event object. Next is
int nret = WSAEventSelect (M_soclisten,
M_hevent,
Fd_accept);
Associates this event object with a M_soclisten socket. This object will be believed when fd_accept this network event occurs on the M_soclisten.
2: In Ciocpserver::listenthreadproc This function, this variable has the following action
Dwret = wsawaitformultipleevents (1,
&pthis->m_hevent,
FALSE,
100,
FALSE);
Wait for the event object to be believable.
int nret = wsaenumnetworkevents (Pthis->m_soclisten,
Pthis->m_hevent,
&events);
When the event object is trusted, enumerate the network events that occur on the event object and determine whether the expected network events occur.
3: This action is done in Ciocpserver::shutdown this function for this variable
Wsacloseevent (m_hevent);
From the above analysis, we can draw a conclusion that the existence of this m_hevent is to give this listener socket to do an event representation, that is, all occurrences of the event on this socket is reflected by this event object.
Next we need to look at this function: Ciocpserver:: Closecompletionport, and see what happens in this function.
First, let's look at the ciocpserver::m_nworkercnt variable.
1: In this function of CIOCPSERVER::INITIALIZEIOCP, there is this operation for this variable.
As you can see, this value represents the number of threads that are serving the completion port.
2: In the Ciocpserver::threadpoolfunc function, there is this action for this variable
InterlockedDecrement (&PTHIS->M_NWORKERCNT);
This operation is an operation at the end of a thread that completes the port service
3: In the Ciocpserver::closecompletionport function, the operation of this variable is not much.
From the above analysis, we can conclude that the value of this m_nworkercnt represents the number of threads to complete the port service, because this value is a global variable, so when each thread accesses this value, it must perform a synchronous-atomic operation on access to this value.