C++ 可执行文件输入参数

1. 输入参数选项处理

在生成 elf 可执行文件时,对输入的参数做解析。

解析代码:

int main(int argc, char *argv[])  {
        std::string source, output;
    int isencode = 0;
    int c;
    while((c = getopt_long(argc, argv, short_options, long_options, nullptr)) != -1) {
        printf("[+]get options : %d \n", c);
        switch (c) {
            case 'e':
                source = optarg;
                isencode = 1;
                break;
            case 'd':
                source = optarg;
                isencode = 2;
                break;
            case 'o':
                output = optarg;
                break;
            case 'h':
                useage();
                break;
            default:
                break;
        }
    }
}

以上就是对参数命令的解析。同时需要设置命令选项:

const char* short_options = "hdm:d:e:o:";    // 带参数的,要使用的命令,需要在这里声明
const struct option long_options[] = {
        {"help", 0, NULL, 'h'},
        {"decode", 1, NULL, 'd'},
        {"encode", 1, NULL, 'e'},
    {"output", 1, NULL, 'o'},
        {nullptr, 0, nullptr, 0}
};
void useage();

void useage() {
    printf(" Options are:\n");

    printf("  -d --decode                                DecryptionAES  \n");
    printf("  -e --memso memBaseAddr(16bit format)       EncryptionAES \n");
    printf("  -o --output generateFilePath               Generate file path\n");
    printf("  -h --help                                  Display this information\n");
}

long_options[] 对应 getopt_long 函数,这个标准函数如下:

参数longopts,其实是一个结构的实例:
struct option {
const char *name; //name表示的是长参数名
int has_arg; //has_arg有3个值,no_argument(或者是0),表示该参数后面不跟参数值
// required_argument(或者是1),表示该参数后面一定要跟个参数值
// optional_argument(或者是2),表示该参数后面可以跟,也可以不跟参数值
int *flag;
//用来决定,getopt_long()的返回值到底是什么。如果flag是null(通常情况),则函数会返回与该项option匹配的val值;如果flag不是NULL,则将val值赋予flag所指向的内存,并且返回值设置为0。
int val; //和flag联合决定返回值
}

就是为 1 时,后面可跟参数。

2. 完整示例如下:

#include   
#include "AES.h"  
#include "Base64.h"  

#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

const char* short_options = "hdm:d:e:o:";
const struct option long_options[] = {
        {"help", 0, NULL, 'h'},
        {"decode", 1, NULL, 'd'},
        {"encode", 1, NULL, 'e'},
        {"output", 1, NULL, 'o'},
        {nullptr, 0, nullptr, 0}
};
void useage();
int main(int argc, char *argv[])  
{  
/*    string str1;
    cin >> str1; 
    cout << "加密前:" << str1 << endl;
    string str2 = EncryptionAES(str1);  
    cout << "加密后:" << str2 << endl;  
    string str3 = DecryptionAES(str2);  
    cout << "解密后:" << str3 << endl;  */
    std::string source, output;
    int isencode = 0;
    int c;
    while((c = getopt_long(argc, argv, short_options, long_options, nullptr)) != -1) {
        printf("[+]get options : %d \n", c);
        switch (c) {
            case 'e':
                source = optarg;
                isencode = 1;
                break;
            case 'd':
                source = optarg;
                isencode = 2;
                break;
            case 'o':
                output = optarg;
                break;
            case 'h':
                useage();
                break;
            default:
                break;
        }
    }
    printf("[-]open  %s gooooo, cnum : %d \n",source.c_str(), c);
    
    int fd=open(source.c_str(), O_RDWR);
    if(!fd) {
        printf("source so file cannot found!!!\n");
        return -1;
    }
    struct stat buf={0};
    printf("step 1 \n");
    int status=stat(source.c_str(),&buf);            // 获取文件信息
    printf("[+]fstat %s path, size : %d \n",source.c_str(), buf.st_size);
    if (status==-1) {
        printf("[-]fstat %s failed \n",source.c_str());
        return -1;
    }
    printf("step 2 \n");
    int g_dexSize = buf.st_size;
    printf("step 3 \n");
    char *readbuf = new char[g_dexSize];
    printf("step 4 \n");
    int ret = read(fd, readbuf, g_dexSize);
    printf("step 5 ret: %d \n", ret);
    if (ret != g_dexSize) {
        printf("[-]read %d failed",g_dexSize);
    }
    printf("step 6 \n");
    char *rbuf = readbuf;
    string s = rbuf;
    string rstr = "";
    int lenss = s.length();
    printf("step 7 lensss : %d\n", lenss);
    if (isencode == 1) {
        rstr = EncryptionAES(s);
        printf("step 8 rstr\n");
    }
    if (isencode == 2) {
        rstr = DecryptionAES(s);
    }
    printf("step 9 \n");
    const char *t = rstr.data();
    printf("step 10 t : %c \n", t);
    int len = rstr.length();
    printf("[+]encode %d length \n", len);
    
    
    auto wfd=fopen(output.c_str(), "wb+");
    if(nullptr == wfd) {
        printf("output so file cannot write !!!\n");
        return -1;
    }
    printf("step 11 wfd\n");
    //int wsize = write(wfd, t, len);
    int wsize = fwrite(t, len, 1, wfd);
    printf("step 12 wfd : %d \n", wsize);
    if (wsize != 1) {
        printf("[-]encode %d error", wsize);
    }
    close(fd);
    fclose(wfd);
    printf("step 13 end \n");
    return 0;
}

void useage() {
    printf(" Options are:\n");

    printf("  -d --decode                                DecryptionAES  \n");
    printf("  -e --memso memBaseAddr(16bit format)       EncryptionAES \n");
    printf("  -o --output generateFilePath               Generate file path\n");
    printf("  -h --help                                  Display this information\n");
}

你可能感兴趣的:(C++ 可执行文件输入参数)