Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: Selektiivinen segfault / älykkyystesti

Turakointi [16.04.2020 00:31:03]

#

Nykyään monen omisteisen ohjelman käyttökokemus ja suosio perustuu ainakin osittain siihen, että käyttäjälle annetaan valheellinen osaamisen tunne. Näiden käyttäjäkuntaan kehittyy toksinen ilmapiiri, jossa haukutaan tyhmäksi ja osaamattomaksi sellaiset käyttäjät, joilla kyseinen ohjelma ei jostain syystä toimi, vaikka vika selvästi olisikin ohjelmassa itsessään. Tämä ohjelma ei tee mitään hyödyllistä, mutta demonstroi muistialueen ylitystä, jonka se tekee käyttäjänimen perusteella.

/*

  **  Selektiivinen segfault  **

  Tämä ohjelma tekee muistialueen ylityksen käyttäjänimen perusteella. Ohjelman tarkoituksena on todistaa, että muistialueen ylitys johtuu ohjelmakoodista itsestään, eikä käyttäjä voi vaikuttaa
  siihen. Todellisessa elämässä muistialueen ylitykseen johtavan koodin suorittaminen johtuu yleensä muista muuttujista kuin käyttäjänimestä. Ohjelman tarkoitus on ottaa kantaa siihen
  toksiseen ilmapiiriin, joka aiheuttaa tiettyjen suljetun lähdekoodin ohjelmien fanikunnan keskuudessa haukkumista ja kiusaamista niitä käyttäjiä kohtaan, joilla ohjelma ei toimi kunnolla.

*/

// Määritellään, kuka on tyhmä
#define _STUPID "sami"

#include <stdio.h>
#include <stdlib.h>

void main()
{
  // Teksti, joka näytetään ohjelman suorittavalle käyttäjälle, jos käyttäjänimi ei ole sama kuin merkkijono stupid[]
  char hello[] = "Hello world!\n";
  // pointteri käyttäjänimeen
  char *user;
  // Tyhmän käyttäjän käyttäjänimi. Tällä käyttäjällä ohjelma ei toimi, vaan tekee muistialueen ylityksen, koska käyttäjä on tyhmä.
  char stupid[] = _STUPID;
  /* Pointteri tyhmän käyttäjän käyttäjänimeen, koska C-kielessä ei saa inkrementoida staattisten merkkijonojen alkupointteria. Tämä nopeuttaa ohjelman suoritusta verrattuna siihen, että
   käytettäisiin erillistä offset-muuttujaa. Tuotettu assembly-koodi on myös hankalampaa tulkita kuin käyttämällä offset-muuttujaa. */
  char *stupidp = stupid;
  // offset-muuttuja hello[]-merkkijonon tulostusta varten.
  unsigned int n=0;

  /* otetaan käyttäjänimi talteen ympäristömuuttujista. Yritetään ensin POSIX-yhteensopivien järjestelmien ympäristömuuttujaa USER. Jos sitä ei löydy, otetaan WINDOWS-yhteensopivien
   järjestelmien ympäristömuuttuja USERNAME. Jos sitäkään ei löydy, lopetetaan ohjelman suoritus.*/
  if(!(user = getenv("USER")))
    if(!(user = getenv("USERNAME")))
      return;

  /* tarkistetaan käyttäjän älykkyysosamäärä, eli tarkistetaan joka kerta pointterien inkrementointien välissä  ettei nollatavu ole vielä tullut merkkijonoissa vastaan, ja samalla tarkistetaan
  onko merkkijonojen senhetkisten solujen
   sisältö sama.*/
  while(*user && *stupidp && *user == *stupidp)
  {
    user++;
    stupidp++;
  }

  /* jos käyttäjä on tyhmä (nollatavut molemmissa osoittimissa), siirretään hello[]-merkkijonon ensimmäisestä tavusta lähtien kaikkien seuraavien muistiosoitteiden sisältö aina edelliseen
   muistiosoitteeseen, joka johtaa varmasti muistialueen ylitykseen. */
  if(!*stupidp && !*user)
    while(1)
      hello[n] = hello[++n];

  // jos käyttäjä ei ole tyhmä, näytetään normaalisti Hello World! -teksti.
  while(hello[n])
    putc(hello[n++], stdout);

}

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta