Linux programming to your program back door

Source: Internet
Author: User
Tags message queue strtok

The "Back door" here is not to teach you to do bad things, but to let you do good, build your own debugging tools to better debug development. We all know that when the program has an exception error, we need to locate the error, and sometimes we also want to, we do not modify the program, we can use the log to locate the error? Some people will say, I add more points in my program to print, and every step of the program I will add a line to print, when the log will know the program at which step died. This method might work in a small program, but in a large system with hundreds of logs per second, how can we find the log of the one we want in this vast log? The workload was exaggerated. The solution in the project is to open a backdoor to your own program that is designed for developers to debug the program. In my previous article, "Custom Band-level log for Linux programming" describes how to customize your own band-level log, and we can change the level of log in our backdoor so that the log is changed without having to re-modify the program. For example, we initialize our log level is fatal, then only print out the fatal information, but one time the program error, but we can not see from the fatal log, we change the log level to the background of alarm, We identified the cause of the program error by alarm log. Of course, we can do this through the back door is not only these, specifically, the back door is our program eye and running the program to communicate a door. There are a few key points to building such a program backdoor:
    • Open a thread in the process to act as the Debug center
    • The thread receives the command that the developer passed to it through the FIFO
    • Parse these commands
    • Scripting a simple command-line interface

First, create a debug center threadThis is nothing to say, I used the last article "Linux Programming Custom Message Queue" Set up a message queue framework, the msg_sender1 into a debug_center thread, as our program back door, we interact with the program from here to start.
if (pthread_create (&debug_thread_id, NULL, (void*) debug_center, null)) {    My_log (FATAL, "Create Debug Center Fail!\n ");    return-1;}

Second, create FIFOWhy create FIFO (Named pipes)? Because we need to communicate with our program, we need to tell the program our instructions, then we need a communication channel, FIFO is a good choice. We put our instructions in the pipeline, the program will take the instructions out of the pipeline, and then execute the instructions, and this way our program backdoor communication model is out. Why is solved, it's time to solve how. For the operation of the pipe, I do this:
System ("Rm/vob/ljsdpoenew3/exercise/debug_log");   Every time we enter the Debug center we will delete the original FIFO file, avoid affecting the rear operation rc = Mkfifo ("/vob/ljsdpoenew3/exercise/debug_log", 0666);  Create FIFOIF (RC < 0) {   my_log (DEBUG, "make FIFO fail!\n");   Pthread_exit (0);} fp = fopen ("/vob/ljsdpoenew3/exercise/debug_log", "R");  Open FIFO, read instruction if (fp = = NULL) {    my_log (DEBUG, "open Debug_log fail!\n");    Pthread_exit (0);}

Read FIFO we solved, then how to write our instructions into the FIFO? Here I intend to use the Read command from the shell, which will explain how to implement it later.

Iii. Analytic DirectivesThe parsing instructions can also be divided into two steps:
    1. To parse the data from FIFO, for example, I defined D d to mean display debug, which shows the current debug level, then our program has to format the original data first.
    2. The command is parsed and the corresponding operation is performed.
Format processing:
static int Get_args (FILE *inputfile) {    char tmpbuffer[100];    char *line = tmpbuffer;    Char separator[] = ", \n\t";    char *token;    int  i;    char EOF;     int num = 0;     EOF =!fgets (line, sizeof (Tmpbuffer), inputfile);    if (EOF)        return num;     token = strtok (line, separator);    while (Num < Max_num_args && token)    {        strcpy (Args[num], token);        num++;        token = strtok (NULL, separator);    }     for (i = num; i < Max_num_args; i++)        args[i][0] = 0;     return num;}

Command parsing:
        Switch (args[0][0])//parse instruction to see what each instruction corresponds to {case ' d '://display switch (args[1][0]                    {case ' Q '://display queue show_mq (FD);                    Break                    Case ' d '://display debug Show_debug_level (FD);                     Break                        Default:help_manual (FD);                Break             } break;                    Case ' s '://set switch (args[1][0]) {case ' d '://set debug level  n = atoi (args[2]);                    Converts a string to an integer fprintf (FD, "debug level changed from%d to%d", global.debug_level,n);  Global.debug_level = n;                     Change log level break;                        Default:help_manual (FD);                Break             } break; DefAult:help_manual (FD);        Break  }

Iv. Building the Debug interfaceFirst on the interface diagram:

Every command we knock is passed through the interface to the end of the program, such as "D D" indicates that the current system is running at the log level, and "s D" is to set the log level we want to see, so that we can implement the program through the backdoor dynamic modification of the program. So how do you implement this seemingly simple interface? To implement this interface, there are several key points:
    • We need to redirect the printout of the program to a file.
    • Read the contents of a file using a shell script
    • The command we entered needs to be written to the FIFO.
The above three points are the most important technical issues for the interface.
    1. REDIRECT Output
At first I was going to redirect the standard output and standard error to the amount in the file, but think about it, or want to directly print the content directly to the file. such as this:
     FD = fopen ("/vob/ljsdpoenew3/exercise/debug_log2", "w+");    if (fd = = NULL)    {        my_log (DEBUG, "open debug_log2 fail!\n");        Pthread_exit (0);    } fprintf (FD, "debug level change from%d to%d", global.debug_level,n);
In this way, the print generated by Debug Center is output to the file debug_log2.

2. Read the content with a script and write the content to the FIFO

To do this requires a simple knowledge of shell programming, how do we put our input into the FIFO? How do we read the contents of the log file and display it on the display? I think the first is to write another client, for interprocess communication, write the command to the FIFO, but also read the contents of the log file. However, I found that using the shell can do the above, and it only takes a few lines of code.
#!/bin/bash my_inp_fifo=/vob/ljsdpoenew3/exercise/debug_log    # Specify FIFO file Stty erase ^h while     [true];d o         Read INP    #循环读入用户输入        If ["$inp" = = "Quit"];then   #quit代表结束该界面                exit 0        fi        echo $inp > $my _inp_ FIFO   #写入fifo        cat debug_log2.txt         #显示log的内容done

Let's see how this command-line interface runs! First we run the server process
The sever process constantly generates messages and processes messages.   We open another window and execute the script./test.sh, enter the interface we used the D command to see the debug level of the program at this time, using the D q to see the program message queue situation. We used the S-d instruction to set the debug level to 0, when the screen did not have any printout, and when we used the S-d instruction to set levels to-1 (all positions one), all the print classes were turned on and the screen began to print wildly. Also said that we control the program through the backdoor, here we just modified the log level of the program, of course, we can do more things, as long as the framework to the inside with instructions, and corresponding processing operations, can be achieved. v. SummaryThe so-called back door, is a can control the program interface, this interface is only for developers debugging development, not open to customers. So the back door has a huge effect, so it's a great tool for developers to debug programs. Some people will think, I want to use a socket instead of FIFO for process communication can not, so you can do remote host control program.   I think it is possible, but it is more secure to use Telnet to the destination host and then run the script operation. Finally, the source code framework is given.
  1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <math.h> 5 #incl  Ude <sys/types.h> 6 #include <sys/stat.h> 7 #include <sys/prctl.h> 8 #include "msg_def.h" 9 #include "Global.h" Ten queue_t msgqueue; extern dashboard_t Global; #define Max_num_args #define MAX_ARGS_SIZE (Args[max_num_args][max_args_size]) ;     The static int Get_args (FILE *inputfile,file *fd) {24 char tmpbuffer[100]; char *line = Tmpbuffer; Char separator[] = ", \n\t"; *token Char; int i; + char EOF; int num = 0; EOF =!fgets (line, sizeof (Tmpbuffer), inputfile); if (EOF) return num; memcpy (tmpbuffer2,tmpbuffer,100); The Panax Notoginseng token = strtok (line, separator); (Num < Max_num_args && tokens), strcpy (Args[num], token);num++; token = strtok (NULL, separator); (i = num; i < Max_num_args; i++) args[i][0] = 0; if (num > 0) {fprintf (FD, "%s", TmpBuffer2); Help_manual (file* fd), (FD, "\nd d:display current Debu G level\n "); fprintf (FD, "D q:display msg Queue Length, head and tail\n"); fprintf (FD, "s d [level]: Set debug [level] \ n"); (file* fd) show_mq {fprintf (fd, "msg queue length:%d head:%d tail:%d \ n", ABS (Msgqueue . head-msgqueue.rear), msgqueue.head,msgqueue.rear); Show_debug_level (file* FD), fprintf (FD, "Current debug Level:%d\n", Global.debug_leve L); The "Debug_center" () () () () () () () () () () (rc,num,n), file* FP, file* FD; DEBUG, "hi,debug!\n"); 85 86 System ("Rm/vob/ljsdpoenew3/exercise/debug_log"); System ("RM/VOB/LJSDPOENEW3/EXERCISE/DEBUG_LOG2"); Mkfifo rc = ("/vob/ljsdpoenew3/exercise/debug_log", 0666);     if (RC < 0) My_log (DEBUG, "make FIFO fail!\n"), Pthread_exit (0); 94} 95 96 fp = fopen ("/vob/ljsdpoenew3/exercise/debug_log", "R");   if (fp = = NULL) 98 {my_log (DEBUG, "open Debug_log fail!\n"); pthread_exit (0); 101}102 103 FD = fopen ("/vob/ljsdpoenew3/exercise/debug_log2", "w+"); 104 if (fd = = NULL). {106 My_log (debug , "Open debug_log2 fail!\n"); 107 pthread_exit (0); 108}109//freopen ("/vob/ljsdpoenew3/exercise/debug_log2.             TXT "," w+ ", FD), 111 fprintf (FD," \n==================================================\n "), fprintf (FD," Welcme to Debug center! ");   113 fprintf (FD, "\n==================================================\n\n"); help_manual (FD); 115  Fflush (FD); 117 while (1) 118 {119 fflush (FD); fprintf (FD, "\n\nmy_diag>"); 121 num = Get_args (FP,FD), 122 if (num < 1) 123 {124 Freopen ("/vob/ljsdpoenew3/exercise/debug_log"         , "R", FP), Fflush (FD), 126 continue;127}128 fprintf (FD, "\n\nmy_diag>"); 129                 Switch (args[0][0]) [131 case ' d '://display132 switch (args[1][0]) 133                     {134 case ' Q '://display queue135 show_mq (FD); 136                     break;137 case ' d '://display debug138 show_debug_level (FD); 139                         break;140 141 default:142 help_manual (FD); 143 break;144}145 break;146 147 case ' s '://set148 switch (ARG             S[1][0]) 149    {case ' d '://set debug level151 n = atoi (args[2]); 152                     fprintf (FD, "debug level change from%d to%d", global.debug_level,n); 153 Global.debug_level = n;154                         break;155 156 default:157 help_manual (FD); 158 break;159}160 break;161 162 default:163 Help_manu Al (FD); 164 break;165}166 167}168}

Linux programming to your program back door

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.