c++/přepis-cli-parametrů/přepis-cli-parametrů.cpp
author František Kučera <franta-hg@frantovo.cz>
Tue, 12 May 2020 21:30:46 +0200
changeset 58 2f84ed5f3abf
parent 54 2a22f9959ea3
permissions -rw-r--r--
SQLite: demo modul: extern "C" není potřeba pro SQL funkce
     1 /**
     2  * Přepis CLI parametrů
     3  * Copyright © 2017 František Kučera (frantovo.cz)
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, either version 3 of the License, or
     8  * (at your option) any later version.
     9  *
    10  * This program is distributed in the hope that it will be useful,
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  * GNU General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License
    16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
    17  */
    18 
    19 #include <stdlib.h>
    20 #include <iostream>
    21 #include <wchar.h>
    22 #include <locale.h>
    23 
    24 
    25 using namespace std;
    26 
    27 void cekej() {
    28 	wprintf(L"Stiskněte Enter pro pokračování…");
    29 	getwchar();
    30 }
    31 
    32 void napoveda(const string nazevProgramu) {
    33   wprintf(L"Vypište si parametry jedním z následujících příkazů:\n");
    34   wprintf(L"\tcat /proc/$(pidof %s)/cmdline | xargs -0 -n1 echo\n", nazevProgramu.c_str());
    35   wprintf(L"\tps aux | grep '[ ]%s'\n", nazevProgramu.c_str());
    36 }
    37 
    38 /**
    39  * 1) Program vypíše zadané parametry (argumenty příkazového řádku) a zastaví se (čeká na potvrzení uživatelem).
    40  * 2) Uživatel si vypíše proces a jeho parametry v druhém terminálu.
    41  * 3) Program přepíše svoje parametry – např. 'heslo' → 'xxxxx'.
    42  * 4) Uživatel si opět vypíše informace o procesu a vidí, že původní informace (v praxi např. hesla) jsou pryč.
    43  * 5) Program se ukončí.
    44  */
    45 int main(int argc, char* argv[]) {
    46 
    47 	setlocale(LC_ALL,"");
    48 
    49 	string nazevProgramu = argv[0];
    50 
    51 	if (argc == 1) { // 1 = jen název programu, ale žádné parametry
    52 		wprintf(L"Není, co přepisovat – příště prosím zadejte nějaké parametry – např.\n");
    53 		wprintf(L"\t%s aaa bbb ccc\n", nazevProgramu.c_str());
    54 		return 1;
    55 	}
    56 
    57 	wprintf(L"Přehled zadaných parametrů:\n");
    58 	for (int i = 1; i < argc; i++) {
    59 		wprintf(L"\t%d = %s\n", i, argv[i]);
    60 	}
    61 
    62 	napoveda(nazevProgramu);
    63 	cekej();
    64 
    65 	// Nahradíme všechny znaky ve všech parametrech, aby nebylo možné přečíst původní hodnoty (např. hesla).
    66 	// Pracujeme zde na úrovni bajtů, takže pokud parametr obsahoval vícebajtové znaky, bude mít po nahrazení více znaků (ale stejně bajtů).
    67 	// Stále bude možné zjistit délku původních parametrů (v bajtech).
    68 	for (int i = 1; i < argc; i++) {
    69 		char * arg = argv[i];
    70 		while (*arg) *arg++= 'x';
    71 	}
    72 	// Pokud bychom začínali od nuly (i = 0), přepsali bychom i samotný název programu!
    73 	// Možná už jste ve výpisu procesů někdy viděli názvy, které neodpovídají žádné binárce.
    74 	// Program se tak může maskovat – nicméně i tak bude symbolický odkaz v /proc/…/exe ukazovat na jeho binárku.
    75 
    76 	wprintf(L"Parametry byly přepsány!\n");
    77 	napoveda(nazevProgramu);
    78 	cekej();
    79 }