首页 > 技术文章 > pwnable.kr-balckjack-Writeup

WangAoBo 原文

MarkdownPad Document

pwnable.kr-balckjack-Writeup

该题的代码奇长无比(788行)但题挺容易,并且比较有意思

  • 首先从提供的网址https://cboard.cprogramming.com/c-programming/114023-simple-blackjack-program.html查看该题用到的代码如下:

      1 // Programmer: Vladislav Shulman
      2 // Final Project
      3 // Blackjack
      4  
      5 // Feel free to use any and all parts of this program and claim it as your own work
      6  
      7 //FINAL DRAFT
      8  
      9 #include <stdlib.h>
     10 #include <stdio.h>
     11 #include <math.h>
     12 #include <time.h>                //Used for srand((unsigned) time(NULL)) command
     13 #include <process.h>             //Used for system("cls") command
     14  
     15 #define spade 06                 //Used to print spade symbol
     16 #define club 05                  //Used to print club symbol
     17 #define diamond 04               //Used to print diamond symbol
     18 #define heart 03                 //Used to print heart symbol
     19 #define RESULTS "Blackjack.txt"  //File name is Blackjack
     20  
     21 //Global Variables
     22 int k;
     23 int l;
     24 int d;
     25 int won;
     26 int loss;
     27 int cash = 500;
     28 int bet;
     29 int random_card;
     30 int player_total=0;
     31 int dealer_total;
     32  
     33 //Function Prototypes
     34 int clubcard();      //Displays Club Card Image
     35 int diamondcard();   //Displays Diamond Card Image
     36 int heartcard();     //Displays Heart Card Image
     37 int spadecard();     //Displays Spade Card Image
     38 int randcard();      //Generates random card
     39 int betting();       //Asks user amount to bet
     40 void asktitle();     //Asks user to continue
     41 void rules();        //Prints "Rules of Vlad's Blackjack" menu
     42 void play();         //Plays game
     43 void dealer();       //Function to play for dealer AI
     44 void stay();         //Function for when user selects 'Stay'
     45 void cash_test();    //Test for if user has cash remaining in purse
     46 void askover();      //Asks if user wants to continue playing
     47 void fileresults();  //Prints results into Blackjack.txt file in program directory
     48  
     49 //Main Function
     50 int main(void)
     51 {
     52     int choice1;
     53     printf("
    ");
     54     printf("
    ");
     55     printf("
    ");
     56     printf("
                  222                111                            ");
     57     printf("
                222 222            11111                              ");
     58     printf("
               222   222          11 111                            "); 
     59     printf("
                    222              111                               "); 
     60     printf("
                   222               111                           ");   
     61     printf("
    ");
     62     printf("
    %c%c%c%c%c     %c%c            %c%c         %c%c%c%c%c    %c    %c                ", club, club, club, club, club, spade, spade, diamond, diamond, heart, heart, heart, heart, heart, club, club);  
     63     printf("
    %c    %c    %c%c           %c  %c       %c     %c   %c   %c              ", club, club, spade, spade, diamond, diamond, heart, heart, club, club);            
     64     printf("
    %c    %c    %c%c          %c    %c     %c          %c  %c               ", club, club, spade, spade, diamond, diamond, heart, club, club);                        
     65     printf("
    %c%c%c%c%c     %c%c          %c %c%c %c     %c          %c %c              ", club, club, club, club, club, spade, spade, diamond, diamond, diamond, diamond, heart, club, club);      
     66     printf("
    %c    %c    %c%c         %c %c%c%c%c %c    %c          %c%c %c             ", club, club, spade, spade, diamond, diamond, diamond, diamond, diamond, diamond, heart, club, club, club);                       
     67     printf("
    %c     %c   %c%c         %c      %c    %c          %c   %c               ", club, club, spade, spade, diamond, diamond, heart, club, club);                                         
     68     printf("
    %c     %c   %c%c        %c        %c    %c     %c   %c    %c             ", club, club, spade, spade, diamond, diamond, heart, heart, club, club);                                                            
     69     printf("
    %c%c%c%c%c%c    %c%c%c%c%c%c%c   %c        %c     %c%c%c%c%c    %c     %c            ", club, club, club, club, club, club, spade, spade, spade, spade, spade, spade, spade, diamond, diamond, heart, heart, heart, heart, heart, club, club);                                                                                     
     70     printf("
    ");     
     71     printf("
                            21                                   ");
     72      
     73     printf("
         %c%c%c%c%c%c%c%c      %c%c         %c%c%c%c%c    %c    %c                ", diamond, diamond, diamond, diamond, diamond, diamond, diamond, diamond, heart, heart, club, club, club, club, club, spade, spade);                     
     74     printf("
            %c%c        %c  %c       %c     %c   %c   %c              ", diamond, diamond, heart, heart, club, club, spade, spade);                                      
     75     printf("
            %c%c       %c    %c     %c          %c  %c               ", diamond, diamond, heart, heart, club, spade, spade);                                           
     76     printf("
            %c%c       %c %c%c %c     %c          %c %c              ", diamond, diamond, heart, heart, heart, heart, club, spade, spade);                                     
     77     printf("
            %c%c      %c %c%c%c%c %c    %c          %c%c %c             ", diamond, diamond, heart, heart, heart, heart, heart, heart, club, spade, spade, spade);                                                
     78     printf("
            %c%c      %c      %c    %c          %c   %c               ", diamond, diamond, heart, heart, club, spade, spade);                                                                               
     79     printf("
         %c  %c%c     %c        %c    %c     %c   %c    %c             ", diamond, diamond, diamond, heart, heart, club, spade, spade);                                                                                                               
     80     printf("
          %c%c%c      %c        %c     %c%c%c%c%c    %c     %c            ", diamond, diamond, diamond, heart, heart, club, club, club, club, club, spade, spade);                                                                                                                                        
     81     printf("
    ");  
     82     printf("
             222                     111                         ");
     83     printf("
            222                      111                         ");
     84     printf("
           222                       111                         ");
     85     printf("
          222222222222222      111111111111111                       ");
     86     printf("
          2222222222222222    11111111111111111                         ");
     87     printf("
    ");
     88     printf("
    ");
     89      
     90     asktitle();
     91      
     92     printf("
    ");
     93     printf("
    ");
     94     system("pause");
     95     return(0);
     96 } //end program
     97  
     98 void asktitle() // Function for asking player if they want to continue
     99 {
    100     char choice1;
    101     int choice2;
    102      
    103      printf("
                     Are You Ready?");
    104      printf("
                    ----------------");
    105      printf("
                          (Y/N)
                            ");
    106      scanf("
    %c",&choice1);
    107  
    108     while((choice1!='Y') && (choice1!='y') && (choice1!='N') && (choice1!='n')) // If invalid choice entered
    109     {                                                                           
    110         printf("
    ");
    111         printf("Incorrect Choice. Please Enter Y for Yes or N for No.
    ");
    112         scanf("%c",&choice1);
    113     }
    114  
    115  
    116     if((choice1 == 'Y') || (choice1 == 'y')) // If yes, continue. Prints menu.
    117     { 
    118             system("cls");
    119             printf("
    Enter 1 to Begin the Greatest Game Ever Played.");
    120             printf("
    Enter 2 to See a Complete Listing of Rules.");
    121             printf("
    Enter 3 to Exit Game. (Not Recommended)");
    122             printf("
    Choice: ");
    123             scanf("%d", &choice2); // Prompts user for choice
    124             if((choice2<1) || (choice2>3)) // If invalid choice entered
    125             {
    126                 printf("
    Incorrect Choice. Please enter 1, 2 or 3
    ");
    127                 scanf("%d", &choice2);
    128             }
    129             switch(choice2) // Switch case for different choices
    130             {   
    131                 case 1: // Case to begin game
    132                    system("cls");
    133                     
    134                    play();
    135                                        
    136                    break;
    137                     
    138                 case 2: // Case to see rules
    139                    system("cls");
    140                    rules();
    141                    break;
    142                     
    143                 case 3: // Case to exit game
    144                    printf("
    Your day could have been perfect.");
    145                    printf("
    Have an almost perfect day!
    
    ");
    146                    system("pause");
    147                    exit(0);
    148                    break;
    149                     
    150                 default:
    151                    printf("
    Invalid Input");
    152             } // End switch case
    153     } // End if loop
    154     
    155              
    156  
    157     else if((choice1 == 'N') || (choice1 == 'n')) // If no, exit program
    158     {
    159         printf("
    Your day could have been perfect.");
    160         printf("
    Have an almost perfect day!
    
    ");
    161         system("pause");
    162         exit(0);
    163     }
    164      
    165     return;
    166 } // End function
    167  
    168 void rules() //Prints "Rules of Vlad's Blackjack" list
    169 {
    170      char choice1;
    171      int choice2;
    172       
    173      printf("
               RULES of VLAD's BLACKJACK");
    174      printf("
              ---------------------------");
    175      printf("
    I.");
    176      printf("
         Thou shalt not question the odds of this game.");
    177      printf("
          %c This program generates cards at random.", spade);
    178      printf("
          %c If you keep losing, you are very unlucky!
    ", diamond);
    179       
    180      printf("
    II.");
    181      printf("
         Each card has a value.");
    182      printf("
          %c Number cards 1 to 10 hold a value of their number.", spade);
    183      printf("
          %c J, Q, and K cards hold a value of 10.", diamond);
    184      printf("
          %c Ace cards hold a value of 11", club);
    185      printf("
         The goal of this game is to reach a card value total of 21.
    ");
    186       
    187      printf("
    III.");
    188      printf("
         After the dealing of the first two cards, YOU must decide whether to HIT or STAY.");
    189      printf("
          %c Staying will keep you safe, hitting will add a card.", spade);
    190      printf("
         Because you are competing against the dealer, you must beat his hand.");
    191      printf("
         BUT BEWARE!.");
    192      printf("
          %c If your total goes over 21, you will LOSE!.", diamond);
    193      printf("
         But the world is not over, because you can always play again.
    ");
    194      printf("
    %c%c%c YOUR RESULTS ARE RECORDED AND FOUND IN SAME FOLDER AS PROGRAM %c%c%c
    ", spade, heart, club, club, heart, spade);
    195      printf("
    Would you like to go the previous screen? (I will not take NO for an answer)");
    196      printf("
                      (Y/N)
                        ");
    197      scanf("
    %c",&choice1);
    198       
    199      while((choice1!='Y') && (choice1!='y') && (choice1!='N') && (choice1!='n')) // If invalid choice entered
    200     {                                                                           
    201         printf("
    ");
    202         printf("Incorrect Choice. Please Enter Y for Yes or N for No.
    ");
    203         scanf("%c",&choice1);
    204     }
    205  
    206  
    207     if((choice1 == 'Y') || (choice1 == 'y')) // If yes, continue. Prints menu.
    208     { 
    209             system("cls");
    210             asktitle();
    211     } // End if loop
    212     
    213              
    214  
    215     else if((choice1 == 'N') || (choice1 == 'n')) // If no, convinces user to enter yes
    216     {
    217         system("cls");
    218         printf("
                     I told you so.
    ");
    219         asktitle();
    220     }
    221      
    222     return;
    223 } // End function
    224  
    225 int clubcard() //Displays Club Card Image
    226 {
    227      
    228      
    229     srand((unsigned) time(NULL)); //Generates random seed for rand() function
    230     k=rand()%13+1;
    231      
    232     if(k<=9) //If random number is 9 or less, print card with that number
    233     {
    234     //Club Card
    235     printf("-------
    ");
    236     printf("|%c    |
    ", club);
    237     printf("|  %d  |
    ", k);
    238     printf("|    %c|
    ", club);
    239     printf("-------
    ");
    240     }
    241      
    242      
    243     if(k==10) //If random number is 10, print card with J (Jack) on face
    244     {
    245     //Club Card
    246     printf("-------
    ");
    247     printf("|%c    |
    ", club);
    248     printf("|  J  |
    ");
    249     printf("|    %c|
    ", club);
    250     printf("-------
    ");
    251     }
    252      
    253      
    254     if(k==11) //If random number is 11, print card with A (Ace) on face
    255     {
    256     //Club Card
    257     printf("-------
    ");
    258     printf("|%c    |
    ", club);
    259     printf("|  A  |
    ");
    260     printf("|    %c|
    ", club);
    261     printf("-------
    ");
    262     if(player_total<=10) //If random number is Ace, change value to 11 or 1 depending on dealer total
    263          {
    264              k=11;
    265          }
    266           
    267          else
    268          {
    269  
    270              k=1;
    271          }
    272     }
    273      
    274      
    275     if(k==12) //If random number is 12, print card with Q (Queen) on face
    276     {
    277     //Club Card
    278     printf("-------
    ");
    279     printf("|%c    |
    ", club);
    280     printf("|  Q  |
    ");
    281     printf("|    %c|
    ", club);
    282     printf("-------
    ");
    283     k=10; //Set card value to 10
    284     }
    285      
    286      
    287     if(k==13) //If random number is 13, print card with K (King) on face
    288     {
    289     //Club Card
    290     printf("-------
    ");
    291     printf("|%c    |
    ", club);
    292     printf("|  K  |
    ");
    293     printf("|    %c|
    ", club);
    294     printf("-------
    ");
    295     k=10; //Set card value to 10
    296     }
    297     return k;           
    298 }// End function
    299  
    300 int diamondcard() //Displays Diamond Card Image
    301 {
    302      
    303      
    304     srand((unsigned) time(NULL)); //Generates random seed for rand() function
    305     k=rand()%13+1;
    306      
    307     if(k<=9) //If random number is 9 or less, print card with that number
    308     {
    309     //Diamond Card
    310     printf("-------
    ");
    311     printf("|%c    |
    ", diamond);
    312     printf("|  %d  |
    ", k);
    313     printf("|    %c|
    ", diamond);
    314     printf("-------
    ");
    315     }
    316      
    317     if(k==10) //If random number is 10, print card with J (Jack) on face
    318     {
    319     //Diamond Card
    320     printf("-------
    ");
    321     printf("|%c    |
    ", diamond);
    322     printf("|  J  |
    ");
    323     printf("|    %c|
    ", diamond);
    324     printf("-------
    ");
    325     }
    326      
    327     if(k==11) //If random number is 11, print card with A (Ace) on face
    328     {
    329     //Diamond Card
    330     printf("-------
    ");
    331     printf("|%c    |
    ", diamond);
    332     printf("|  A  |
    ");
    333     printf("|    %c|
    ", diamond);
    334     printf("-------
    ");
    335     if(player_total<=10) //If random number is Ace, change value to 11 or 1 depending on dealer total
    336          {
    337              k=11;
    338          }
    339           
    340          else
    341          {
    342              k=1;
    343          }
    344     }
    345      
    346     if(k==12) //If random number is 12, print card with Q (Queen) on face
    347     {
    348     //Diamond Card
    349     printf("-------
    ");
    350     printf("|%c    |
    ", diamond);
    351     printf("|  Q  |
    ");
    352     printf("|    %c|
    ", diamond);
    353     printf("-------
    ");
    354     k=10; //Set card value to 10
    355     }
    356      
    357     if(k==13) //If random number is 13, print card with K (King) on face
    358     {
    359     //Diamond Card
    360     printf("-------
    ");
    361     printf("|%c    |
    ", diamond);
    362     printf("|  K  |
    ");
    363     printf("|    %c|
    ", diamond);
    364     printf("-------
    ");
    365     k=10; //Set card value to 10
    366     }
    367     return k;
    368 }// End function
    369  
    370 int heartcard() //Displays Heart Card Image
    371 {
    372      
    373      
    374     srand((unsigned) time(NULL)); //Generates random seed for rand() function
    375     k=rand()%13+1;
    376      
    377     if(k<=9) //If random number is 9 or less, print card with that number
    378     {
    379     //Heart Card
    380     printf("-------
    ");
    381     printf("|%c    |
    ", heart); 
    382     printf("|  %d  |
    ", k);
    383     printf("|    %c|
    ", heart);
    384     printf("-------
    ");
    385     }
    386      
    387     if(k==10) //If random number is 10, print card with J (Jack) on face
    388     {
    389     //Heart Card
    390     printf("-------
    ");
    391     printf("|%c    |
    ", heart);
    392     printf("|  J  |
    ");
    393     printf("|    %c|
    ", heart);
    394     printf("-------
    ");
    395     }
    396      
    397     if(k==11) //If random number is 11, print card with A (Ace) on face
    398     {
    399     //Heart Card
    400     printf("-------
    ");
    401     printf("|%c    |
    ", heart);
    402     printf("|  A  |
    ");
    403     printf("|    %c|
    ", heart);
    404     printf("-------
    ");
    405     if(player_total<=10) //If random number is Ace, change value to 11 or 1 depending on dealer total
    406          {
    407              k=11;
    408          }
    409           
    410          else
    411          {
    412              k=1;
    413          }
    414     }
    415      
    416     if(k==12) //If random number is 12, print card with Q (Queen) on face
    417     {
    418     //Heart Card
    419     printf("-------
    ");
    420     printf("|%c    |
    ", heart);
    421     printf("|  Q  |
    ");
    422     printf("|    %c|
    ", heart);
    423     printf("-------
    ");
    424     k=10; //Set card value to 10
    425     }
    426      
    427     if(k==13) //If random number is 13, print card with K (King) on face
    428     {
    429     //Heart Card
    430     printf("-------
    ");
    431     printf("|%c    |
    ", heart);
    432     printf("|  K  |
    ");
    433     printf("|    %c|
    ", heart);
    434     printf("-------
    ");
    435     k=10; //Set card value to 10
    436     }
    437     return k;
    438 } // End Function
    439  
    440 int spadecard() //Displays Spade Card Image
    441 {
    442      
    443      
    444     srand((unsigned) time(NULL)); //Generates random seed for rand() function
    445     k=rand()%13+1;
    446      
    447     if(k<=9) //If random number is 9 or less, print card with that number
    448     {
    449     //Spade Card
    450     printf("-------
    ");
    451     printf("|%c    |
    ", spade);
    452     printf("|  %d  |
    ", k);
    453     printf("|    %c|
    ", spade);
    454     printf("-------
    ");
    455     }
    456      
    457     if(k==10) //If random number is 10, print card with J (Jack) on face
    458     {
    459     //Spade Card
    460     printf("-------
    ");
    461     printf("|%c    |
    ", spade);
    462     printf("|  J  |
    ");
    463     printf("|    %c|
    ", spade);
    464     printf("-------
    ");
    465     }
    466      
    467     if(k==11) //If random number is 11, print card with A (Ace) on face
    468     {
    469     //Spade Card
    470     printf("-------
    ");
    471     printf("|%c    |
    ", spade);
    472     printf("|  A  |
    ");
    473     printf("|    %c|
    ", spade);
    474     printf("-------
    ");
    475     if(player_total<=10) //If random number is Ace, change value to 11 or 1 depending on dealer total
    476          {
    477              k=11;
    478          }
    479           
    480          else
    481          {
    482              k=1;
    483          }
    484     }
    485      
    486     if(k==12) //If random number is 12, print card with Q (Queen) on face
    487     {
    488     //Spade Card
    489     printf("-------
    ");
    490     printf("|%c    |
    ", spade);
    491     printf("|  Q  |
    ");
    492     printf("|    %c|
    ", spade);
    493     printf("-------
    ");
    494     k=10; //Set card value to 10
    495     }
    496      
    497     if(k==13) //If random number is 13, print card with K (King) on face
    498     {
    499     //Spade Card
    500     printf("-------
    ");
    501     printf("|%c    |
    ", spade);
    502     printf("|  K  |
    ");
    503     printf("|    %c|
    ", spade);
    504     printf("-------
    ");
    505     k=10; //Set card value to 10
    506     }
    507     return k;
    508 } // End Function
    509  
    510 int randcard() //Generates random card
    511 {
    512       
    513                 
    514      srand((unsigned) time(NULL)); //Generates random seed for rand() function
    515      random_card = rand()%4+1;
    516       
    517      if(random_card==1)
    518      {   
    519          clubcard();
    520          l=k;
    521      }
    522       
    523      if(random_card==2)
    524      {
    525          diamondcard();
    526          l=k;
    527      }
    528       
    529      if(random_card==3)
    530      {
    531          heartcard();
    532          l=k;
    533      }
    534           
    535      if(random_card==4)
    536      {
    537          spadecard();
    538          l=k;
    539      }    
    540      return l;
    541 } // End Function   
    542  
    543 void play() //Plays game
    544 {
    545       
    546      int p=0; // holds value of player_total
    547      int i=1; // counter for asking user to hold or stay (aka game turns)
    548      char choice3;
    549       
    550      cash = cash;
    551      cash_test();
    552      printf("
    Cash: $%d
    ",cash); //Prints amount of cash user has
    553      randcard(); //Generates random card
    554      player_total = p + l; //Computes player total
    555      p = player_total;
    556      printf("
    Your Total is %d
    ", p); //Prints player total
    557      dealer(); //Computes and prints dealer total
    558      betting(); //Prompts user to enter bet amount
    559         
    560      while(i<=21) //While loop used to keep asking user to hit or stay at most twenty-one times
    561                   //  because there is a chance user can generate twenty-one consecutive 1's
    562      {
    563          if(p==21) //If user total is 21, win
    564          {
    565              printf("
    Unbelievable! You Win!
    ");
    566              won = won+1;
    567              cash = cash+bet;
    568              printf("
    You have %d Wins and %d Losses. Awesome!
    ", won, loss);
    569              dealer_total=0;
    570              askover();
    571          }
    572       
    573          if(p>21) //If player total is over 21, loss
    574          {
    575              printf("
    Woah Buddy, You Went WAY over.
    ");
    576              loss = loss+1;
    577              cash = cash - bet;
    578              printf("
    You have %d Wins and %d Losses. Awesome!
    ", won, loss);
    579              dealer_total=0;
    580              askover();
    581          }
    582       
    583          if(p<=21) //If player total is less than 21, ask to hit or stay
    584          {         
    585              printf("
    
    Would You Like to Hit or Stay?");
    586               
    587              scanf("%c", &choice3);
    588              while((choice3!='H') && (choice3!='h') && (choice3!='S') && (choice3!='s')) // If invalid choice entered
    589              {                                                                           
    590                  printf("
    ");
    591                  printf("Please Enter H to Hit or S to Stay.
    ");
    592                  scanf("%c",&choice3);
    593              }
    594  
    595  
    596              if((choice3=='H') || (choice3=='h')) // If Hit, continues
    597              { 
    598                  randcard();
    599                  player_total = p + l;
    600                  p = player_total;
    601                  printf("
    Your Total is %d
    ", p);
    602                  dealer();
    603                   if(dealer_total==21) //Is dealer total is 21, loss
    604                   {
    605                       printf("
    Dealer Has the Better Hand. You Lose.
    ");
    606                       loss = loss+1;
    607                       cash = cash - bet;
    608                       printf("
    You have %d Wins and %d Losses. Awesome!
    ", won, loss);
    609                       dealer_total=0;
    610                       askover();
    611                   } 
    612       
    613                   if(dealer_total>21) //If dealer total is over 21, win
    614                   {                      
    615                       printf("
    Dealer Has Went Over!. You Win!
    ");
    616                       won = won+1;
    617                       cash = cash+bet;
    618                       printf("
    You have %d Wins and %d Losses. Awesome!
    ", won, loss);
    619                       dealer_total=0;
    620                       askover();
    621                   }
    622              }
    623              if((choice3=='S') || (choice3=='s')) // If Stay, does not continue
    624              {
    625                 printf("
    You Have Chosen to Stay at %d. Wise Decision!
    ", player_total);
    626                 stay();
    627              }
    628           }
    629              i++; //While player total and dealer total are less than 21, re-do while loop 
    630      } // End While Loop
    631 } // End Function
    632  
    633 void dealer() //Function to play for dealer AI
    634 {
    635      int z;
    636       
    637      if(dealer_total<17)
    638      {
    639       srand((unsigned) time(NULL) + 1); //Generates random seed for rand() function
    640       z=rand()%13+1;
    641       if(z<=10) //If random number generated is 10 or less, keep that value
    642       {
    643          d=z;
    644           
    645       }
    646       
    647       if(z>11) //If random number generated is more than 11, change value to 10
    648       {
    649          d=10;
    650       }
    651       
    652       if(z==11) //If random number is 11(Ace), change value to 11 or 1 depending on dealer total
    653       {
    654          if(dealer_total<=10)
    655          {
    656              d=11;
    657          }
    658           
    659          else
    660          {
    661              d=1;
    662          }
    663       }
    664      dealer_total = dealer_total + d;
    665      }
    666            
    667      printf("
    The Dealer Has a Total of %d", dealer_total); //Prints dealer total
    668       
    669 } // End Function 
    670  
    671 void stay() //Function for when user selects 'Stay'
    672 {
    673      dealer(); //If stay selected, dealer continues going
    674      if(dealer_total>=17)
    675      {
    676       if(player_total>=dealer_total) //If player's total is more than dealer's total, win
    677       {
    678          printf("
    Unbelievable! You Win!
    ");
    679          won = won+1;
    680          cash = cash+bet;
    681          printf("
    You have %d Wins and %d Losses. Awesome!
    ", won, loss);
    682          dealer_total=0;
    683          askover();
    684       }
    685       if(player_total<dealer_total) //If player's total is less than dealer's total, loss
    686       {
    687          printf("
    Dealer Has the Better Hand. You Lose.
    ");
    688          loss = loss+1;
    689          cash = cash - bet;
    690          printf("
    You have %d Wins and %d Losses. Awesome!
    ", won, loss);
    691          dealer_total=0;
    692          askover();
    693       }
    694       if(dealer_total>21) //If dealer's total is more than 21, win
    695       {
    696          printf("
    Unbelievable! You Win!
    ");
    697          won = won+1;
    698          cash = cash+bet;
    699          printf("
    You have %d Wins and %d Losses. Awesome!
    ", won, loss);
    700          dealer_total=0;
    701          askover();
    702       }
    703      }
    704      else
    705      {
    706          stay();
    707      }
    708       
    709 } // End Function
    710  
    711 void cash_test() //Test for if user has cash remaining in purse
    712 {
    713      if (cash <= 0) //Once user has zero remaining cash, game ends and prompts user to play again
    714      {
    715         printf("You Are Bankrupt. Game Over");
    716         cash = 500;
    717         askover();
    718      }
    719 } // End Function
    720  
    721 int betting() //Asks user amount to bet
    722 {
    723  printf("
    
    Enter Bet: $");
    724  scanf("%d", &bet);
    725  
    726  if (bet > cash) //If player tries to bet more money than player has
    727  {
    728         printf("
    You cannot bet more money than you have.");
    729         printf("
    Enter Bet: ");
    730         scanf("%d", &bet);
    731         return bet;
    732  }
    733  else return bet;
    734 } // End Function
    735  
    736 void askover() // Function for asking player if they want to play again
    737 {
    738     char choice1;
    739          
    740      printf("
    Would You Like To Play Again?");
    741      printf("
    Please Enter Y for Yes or N for No
    ");
    742      scanf("
    %c",&choice1);
    743  
    744     while((choice1!='Y') && (choice1!='y') && (choice1!='N') && (choice1!='n')) // If invalid choice entered
    745     {                                                                           
    746         printf("
    ");
    747         printf("Incorrect Choice. Please Enter Y for Yes or N for No.
    ");
    748         scanf("%c",&choice1);
    749     }
    750  
    751  
    752     if((choice1 == 'Y') || (choice1 == 'y')) // If yes, continue.
    753     { 
    754             system("cls");
    755             play();
    756     }
    757   
    758     else if((choice1 == 'N') || (choice1 == 'n')) // If no, exit program
    759     {
    760         fileresults();
    761         printf("
    BYE!!!!
    
    ");
    762         system("pause");
    763         exit(0);
    764     }
    765     return;
    766 } // End function
    767  
    768 void fileresults() //Prints results into Blackjack.txt file in program directory
    769 {
    770     FILE *fpresults; //File pointer is fpresults
    771     fpresults = fopen(RESULTS, "w"); //Creates file and writes into it
    772     if(fpresults == NULL) // what to do if file missing from directory
    773     {
    774                printf("
    Error: File Missing
    ");
    775                system("pause");
    776                exit(1);
    777     }
    778     else
    779     {     
    780      fprintf(fpresults,"
    	 RESULTS");
    781      fprintf(fpresults,"
    	---------
    ");
    782      fprintf(fpresults,"
    You Have Won %d Times
    ", won);
    783      fprintf(fpresults,"
    You Have Lost %d Times
    ", loss);
    784      fprintf(fpresults,"
    Keep Playing and Set an All-Time Record!");
    785     } 
    786      fclose(fpresults);
    787      return;
    788 } // End Function
    View Code

    虽然代码足足有近800行,但根据代码的流程逐渐分析,还是能分析出以下信息:

  1. 游戏规则

    • 玩家在每轮游戏开始之前设置赌资;
    • 玩家的任务是通过hit(继续加扑克牌)或者stay(等待)使自己的点数之和等于21;
    • 卡片1~10的点数即为相对应的数字,卡片J,Q,K的点数为10,卡片A的点数为11;
    • 当自己的点数大于了21,或者自己的点数小于了庄家的点数,玩家输;则要从赌本中减去赌资;
    • 当玩家的点数之和等于21时,玩家胜;玩家就从庄家处赚取同赌资金额的金钱;
  2. 当玩家的赌本大于1000000时,胜利,即可拿到flag;


由以上分析,首先先到了三种方法作弊(或者相信自己的人品无穷大,可以通过自己的努力能成为百万富翁):

  1. 直接修改赌本为 ≥ 1000000;
  2. 通过修改, 使自己每局都能获胜,那么需要
  3. 在每局结束时动手脚,增加赌本

分析代码,前两种想法没有找到相应的漏洞,
第三种方法,分析betting函数:

 1 int betting() //Asks user amount to bet
 2 {
 3  printf("

Enter Bet: $");
 4  scanf("%d", &bet);
 5 
 6  if (bet > cash) //If player tries to bet more money than player has
 7  {
 8         printf("
You cannot bet more money than you have.");
 9         printf("
Enter Bet: ");
10         scanf("%d", &bet);
11         return bet;
12  }
13  else return bet;
14 } // End Function
  • 可以看出函数对输入的赌资只做了是否小于赌本的判断,那么我们就可以输入一个负的大小合适的赌本(大小合适指不会数据溢出),如-1000000
  • 那么,如果我们输掉了那一局,我们的赌本就要减负的1000000,就是加正的1000000,就可以拿到flag;

经过几次探索,拿到flag如下:

则flag即为YaY_I_AM_A_MILLIONARE_LOL
2017-2-16 8:16;47

推荐阅读