• Linux编程之给你的程序开后门


    复制代码
            switch(args[0][0])  //解析指令,看每个指令对应哪些意思
            {
                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]);  //将字符串转化为整数
                        fprintf(fd," debug level change from %d to %d",global.debug_level,n);
                        global.debug_level = n;  //更改log级别
                        break;
     
                        default:
                            help_manual(fd);
                            break;
                    }
                    break;
     
                default:
                    help_manual(fd);
                    break;
            }
     
    复制代码
    四、搭建debug界面
    先上界面图:

    我们敲的每个命令都是通过该界面传递到程序那头的,比如“d d”就表示展示出现在系统运行时的log级别,而“s d”就是设置我们想要看的log级别,这样我们就可以实现通过程序后门动态修改程序走向了。
    那该如何实现这个看似简单的交互界面呢?实现该交互界面,有几个关键点:
    • 我们需将程序的打印输出重定向到一个文件里
    • 使用shell脚本读出文件的内容
    • 我们输入的命令需写入到fifo中
    以上三点就是做成界面的最重要的技术问题。
    1. 重定向输出
      一开始我是打算将标准输出、标准错误都重定向到文件里的额,但是想了想,还是想直接把打印内容直接输出到文件就好了。比如这样:
    复制代码
         fd = fopen("/vob/ljsdpoenew3/exercise/debug_log2", "w+");
        if(fd == NULL)
        {
            MY_LOG(DEBUG, "open debug_log2 fail!
    ");
            pthread_exit(0);
        }
    
    fprintf(fd," debug level change from %d to %d",global.debug_level,n);
    复制代码
      这样我们在debug center产生的打印都输出到文件debug_log2上了。

      2.利用脚本读出内容且将内容写入fifo

      要做到这点需要shell编程的简单知识,我们怎么将我们的输入放到fifo呢?我们怎么把log文件的内容读出来显示在显示屏呢?我想到首先是再写个client,进行进程间通信嘛,将命令写到fifo,同时也读出log文件的内容。但是,我发现利用shell就可以做到以上的事了,而且只需花费几行代码。
     
    复制代码
    #!/bin/bash
     
    my_inp_fifo=/vob/ljsdpoenew3/exercise/debug_log    # 指定fifo文件
    stty erase ^H    
     
    while [ true ];
    do
     
            read inp    #循环读入用户输入
            if [ "$inp" == "quit" ];then   #quit代表结束该界面
                    exit 0
            fi
            echo $inp > $my_inp_fifo   #写入fifo
            cat debug_log2.txt         #显示log的内容
    done
    复制代码
    那看看这个命令行界面跑起来是怎么的吧!
    首先我们运行server进程
     
    sever进程不断产生消息并处理消息。
    我们打开另一个窗口,并执行脚本./test.sh,进入界面
     
     
    我们使用了d d命令看到了程序此时的debug级别,用d q看出了程序消息队列的情况。
     
     
    我们使用了s d指令将debug level设置为0,此时屏幕没有任何打印输出,当我们在使用s d指令将level设置为-1(即将所有位置一),此时所有打印级别都打开了,屏幕又开始疯狂打印了。也就说,我们通过后门操控了程序,这里我们只是仅仅修改了程序的log级别,当然我们还可以做更多的事,只要依照这个框架往里面加指令,以及对应的处理操作,就可以实现了。
    五、总结
    所谓后门,就是一个可以操控程序的接口,这个接口仅仅用于开发者调试开发,不会开放给客户。所以这个后门的作用非常巨大,所以是开发者调试程序的一大利器。有人会想,我想用socket来代替fifo进行进程通信可以不,这样就可以做到远程主机操控程序了。我觉得是可以的,但是感觉利用telnet到目的主机再运行脚本操作比较安全。
    最后给出源代码框架
    复制代码
      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <stdlib.h>
      4 #include <math.h>
      5 #include <sys/types.h>
      6 #include <sys/stat.h>
      7 #include <sys/prctl.h>
      8 #include "msg_def.h"
      9 #include "global.h"
     10  
     11 extern Queue_t MsgQueue;
     12 extern dashboard_t global;
     13  
     14  
     15 #define  MAX_NUM_ARGS  20
     16 #define  MAX_ARGS_SIZE  56
     17  
     18 static char args[MAX_NUM_ARGS][MAX_ARGS_SIZE];
     19  
     20 static int get_args(FILE *inputFile,FILE *fd)
     21 {
     22     char tmpBuffer[100];
     23     char tmpBuffer2[100];
     24     char *line = tmpBuffer;
     25     char separator[] = " ,
    	";
     26     char *token;
     27     int  i;
     28     char eof;
     29  
     30     int num = 0;
     31  
     32     eof = !fgets(line, sizeof(tmpBuffer), inputFile);
     33     if (eof)
     34         return num;
     35  
     36     memcpy(tmpBuffer2,tmpBuffer,100);
     37  
     38  
     39     token = strtok(line, separator);
     40     while (num < MAX_NUM_ARGS && token)
     41     {
     42         strcpy(args[num], token);
     43         num++;
     44         token = strtok(NULL, separator);
     45     }
     46  
     47     for (i = num; i < MAX_NUM_ARGS; i++)
     48         args[i][0] = 0;
     49  
     50     if(num > 0)
     51     {
     52         fprintf(fd, "%s", tmpBuffer2);
     53     }
     54  
     55     return num;
     56 }
     57  
     58  
     59 static void help_manual(FILE* fd)
     60 {
     61     fprintf(fd,"
    d d         :           display current debug level
    ");
     62     fprintf(fd,"d q         :           display msg queue length, head and tail
    ");
     63     fprintf(fd,"s d [level] :           set debug [level] 
    ");
     64 }
     65  
     66 static void show_MQ(FILE* fd)
     67 {
     68     fprintf(fd," msg queue length:%d  head:%d  tail:%d 
    ",abs(MsgQueue.head-MsgQueue.rear),MsgQueue.head,MsgQueue.rear);
     69 }
     70  
     71 static void show_debug_level(FILE* fd)
     72 {
     73     fprintf(fd," current debug level: %d
    ", global.debug_level);
     74 }
     75  
     76  
     77  
     78 void debug_center()
     79 {
     80     int rc,num,n;
     81     FILE* fp;
     82     FILE* fd;
     83  
     84     MY_LOG(DEBUG,"Hi,debug!
    ");
     85  
     86  
     87     system("rm /vob/ljsdpoenew3/exercise/debug_log");
     88     system("rm /vob/ljsdpoenew3/exercise/debug_log2");
     89     rc = mkfifo("/vob/ljsdpoenew3/exercise/debug_log", 0666);
     90     if(rc < 0)
     91     {
     92        MY_LOG(DEBUG, "make fifo fail!
    ");
     93        pthread_exit(0);
     94     }
     95  
     96     fp = fopen("/vob/ljsdpoenew3/exercise/debug_log", "r");
     97     if(fp == NULL)
     98     {
     99         MY_LOG(DEBUG, "open debug_log fail!
    ");
    100         pthread_exit(0);
    101     }
    102  
    103     fd = fopen("/vob/ljsdpoenew3/exercise/debug_log2", "w+");
    104     if(fd == NULL)
    105     {
    106         MY_LOG(DEBUG, "open debug_log2 fail!
    ");
    107         pthread_exit(0);
    108     }
    109     //freopen("/vob/ljsdpoenew3/exercise/debug_log2.txt", "w+", fd);
    110  
    111     fprintf(fd,"  
    ==================================================
    ");
    112     fprintf(fd,"             Welcme to Debug Center!");
    113     fprintf(fd,"  
    ==================================================
    
    ");
    114     help_manual(fd);
    115     //fflush(fd);
    116  
    117     while(1)
    118     {
    119         fflush(fd);
    120         fprintf(fd,"
    
    my_diag>");
    121         num = get_args(fp,fd);
    122         if(num < 1)
    123         {
    124             freopen("/vob/ljsdpoenew3/exercise/debug_log", "r", fp);
    125             fflush(fd);
    126             continue;
    127         }
    128         fprintf(fd,"
    
    my_diag>");
    129         switch(args[0][0])
    130         {
    131             case 'd':    //display
    132                 switch(args[1][0])
    133                 {
    134                     case 'q':   //display queue
    135                     show_MQ(fd);
    136                     break;
    137                     case 'd':   //display debug
    138                     show_debug_level(fd);
    139                     break;
    140  
    141                     default:
    142                         help_manual(fd);
    143                         break;
    144                 }
    145                 break;
    146  
    147             case 's':    //set
    148                 switch(args[1][0])
    149                 {
    150                     case 'd': //set debug level
    151                     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_manual(fd);
    164                 break;
    165         }
    166  
    167     }
    168 }
    复制代码
  • 相关阅读:
    BA 的职责
    How to grow up as a BA
    打开struts-config.xml 报错 解决方法Could not open the editor
    eclipse中svn插件的工程不能与svn资源库同步的解决方法
    三种常用的MySQL建表语句(转)
    MySQL中CURRENT_TIMESTAMP(转)
    JavaWeb之CSS详解
    如何在Mac OSX系统下安装Tomcat
    JavaWeb之XML详解
    JavaWeb之HTML入门及常用标签
  • 原文地址:https://www.cnblogs.com/xieyulin/p/7060870.html
Copyright © 2020-2023  润新知