LCOV - code coverage report
Current view: top level - appsec_hw1 - giftcardreader.c (source / functions) Hit Total Coverage
Test: giftcardreader.info Lines: 60 161 37.3 %
Date: 2020-09-15 15:37:12 Functions: 4 6 66.7 %

          Line data    Source code
       1             : /*
       2             :  * Gift Card Reading Application
       3             :  * Original Author: Shoddycorp's Cut-Rate Contracting
       4             :  * Comments added by: Justin Cappos (JAC) and Brendan Dolan-Gavitt (BDG)
       5             :  * Maintainer:
       6             :  * Date: 8 July 2020
       7             :  */
       8             : 
       9             : 
      10             : #include "giftcard.h"
      11             : 
      12             : #include <stdio.h>
      13             : #include <strings.h>
      14             : 
      15             : // interpreter for THX-1138 assembly
      16           0 : void animate(char *msg, unsigned char *program) {
      17             :     unsigned char regs[16];
      18           0 :     char *mptr = msg;
      19           0 :     unsigned char *pc = program;
      20           0 :     int i = 0;
      21           0 :     int zf = 0;
      22           0 :     while (1) {
      23             :         unsigned char op, arg1, arg2;
      24           0 :         op = *pc;
      25           0 :         arg1 = *(pc+1);
      26           0 :         arg2 = *(pc+2);
      27           0 :         switch (*pc) {
      28           0 :             case 0x00:
      29           0 :                 break;
      30           0 :             case 0x01:
      31           0 :                 regs[arg1] = *mptr;
      32           0 :                 break;
      33           0 :             case 0x02:
      34           0 :                 *mptr = regs[arg1];
      35           0 :                 break;
      36           0 :             case 0x03:
      37           0 :                 mptr += (char)arg1;
      38           0 :                 break;
      39           0 :             case 0x04:
      40           0 :                 regs[arg2] = arg1;
      41           0 :                 break;
      42           0 :             case 0x05:
      43           0 :                 regs[arg1] ^= regs[arg2];
      44           0 :                 zf = !regs[arg1];
      45           0 :                 break;
      46           0 :             case 0x06:
      47           0 :                 regs[arg1] += regs[arg2];
      48           0 :                 zf = !regs[arg1];
      49           0 :                 break;
      50           0 :             case 0x07:
      51           0 :                 puts(msg);
      52           0 :                 break;
      53           0 :             case 0x08:
      54           0 :                 goto done;
      55           0 :             case 0x09:
      56           0 :                 pc += (char)arg1;
      57           0 :                 break;
      58           0 :             case 0x10:
      59           0 :                 if (zf) pc += (char)arg1;
      60           0 :                 break;
      61             :         }
      62           0 :         pc+=3;
      63           0 :         if (pc > program+256) break;
      64             :     }
      65           0 : done:
      66           0 :     return;
      67             : }
      68             : 
      69           1 : void print_gift_card_info(struct this_gift_card *thisone) {
      70             :         struct gift_card_data *gcd_ptr;
      71             :         struct gift_card_record_data *gcrd_ptr;
      72             :         struct gift_card_amount_change *gcac_ptr;
      73             :     struct gift_card_program *gcp_ptr;
      74             : 
      75           1 :         gcd_ptr = thisone->gift_card_data;
      76           1 :         printf("   Merchant ID: %32.32s\n",gcd_ptr->merchant_id);
      77           1 :         printf("   Customer ID: %32.32s\n",gcd_ptr->customer_id);
      78           1 :         printf("   Num records: %d\n",gcd_ptr->number_of_gift_card_records);
      79           2 :         for(int i=0;i<gcd_ptr->number_of_gift_card_records; i++) {
      80           1 :                 gcrd_ptr = (struct gift_card_record_data *) gcd_ptr->gift_card_record_data[i];
      81           1 :                 if (gcrd_ptr->type_of_record == 1) {
      82           1 :                         printf("      record_type: amount_change\n");
      83           1 :                         gcac_ptr = gcrd_ptr->actual_record;
      84           1 :                         printf("      amount_added: %d\n",gcac_ptr->amount_added);
      85           1 :                         if (gcac_ptr->amount_added>0) {
      86           1 :                                 printf("      signature: %32.32s\n",gcac_ptr->actual_signature);
      87             :                         }
      88             :                 }       
      89           0 :                 else if (gcrd_ptr->type_of_record == 2) {
      90           0 :                         printf("      record_type: message\n");
      91           0 :                         printf("      message: %s\n",(char *)gcrd_ptr->actual_record);
      92             :                 }
      93           0 :                 else if (gcrd_ptr->type_of_record == 3) {
      94           0 :             gcp_ptr = gcrd_ptr->actual_record;
      95           0 :                         printf("      record_type: animated message\n");
      96           0 :             printf("      message: %s\n", gcp_ptr->message);
      97           0 :             printf("  [running embedded program]  \n");
      98           0 :             animate(gcp_ptr->message, gcp_ptr->program);
      99             :                 }
     100             :         }
     101           1 :         printf("  Total value: %d\n\n",get_gift_card_value(thisone));
     102           1 : }
     103             : 
     104             : // Added to support web functionalities
     105           0 : void gift_card_json(struct this_gift_card *thisone) {
     106             :     struct gift_card_data *gcd_ptr;
     107             :     struct gift_card_record_data *gcrd_ptr;
     108             :     struct gift_card_amount_change *gcac_ptr;
     109           0 :     gcd_ptr = thisone->gift_card_data;
     110           0 :     printf("{\n");
     111           0 :     printf("  \"merchant_id\": \"%32.32s\",\n", gcd_ptr->merchant_id);
     112           0 :     printf("  \"customer_id\": \"%32.32s\",\n", gcd_ptr->customer_id);
     113           0 :     printf("  \"total_value\": %d,\n", get_gift_card_value(thisone));
     114           0 :     printf("  \"records\": [\n");
     115           0 :         for(int i=0;i<gcd_ptr->number_of_gift_card_records; i++) {
     116           0 :         gcrd_ptr = (struct gift_card_record_data *) gcd_ptr->gift_card_record_data[i];
     117           0 :         printf("    {\n");
     118           0 :         if (gcrd_ptr->type_of_record == 1) {
     119           0 :             printf("      \"record_type\": \"amount_change\",\n");
     120           0 :             gcac_ptr = gcrd_ptr->actual_record;
     121           0 :             printf("      \"amount_added\": %d,\n",gcac_ptr->amount_added);
     122           0 :             if (gcac_ptr->amount_added>0) {
     123           0 :                 printf("      \"signature\": \"%32.32s\"\n",gcac_ptr->actual_signature);
     124             :             }
     125             :         }
     126           0 :         else if (gcrd_ptr->type_of_record == 2) {
     127           0 :                         printf("      \"record_type\": \"message\",\n");
     128           0 :                         printf("      \"message\": \"%s\"\n",(char *)gcrd_ptr->actual_record);
     129             :         }
     130           0 :         else if (gcrd_ptr->type_of_record == 3) {
     131           0 :             struct gift_card_program *gcp = gcrd_ptr->actual_record;
     132           0 :                         printf("      \"record_type\": \"animated message\",\n");
     133           0 :                         printf("      \"message\": \"%s\",\n",gcp->message);
     134             :             // programs are binary so we will hex for the json
     135           0 :             char *hexchars = "01234567890abcdef";
     136             :             char program_hex[512+1];
     137           0 :             program_hex[512] = '\0';
     138             :             int i;
     139           0 :             for(i = 0; i < 256; i++) {
     140           0 :                 program_hex[i*2] = hexchars[((gcp->program[i] & 0xf0) >> 4)];
     141           0 :                 program_hex[i*2+1] = hexchars[(gcp->program[i] & 0x0f)];
     142             :             }
     143           0 :                         printf("      \"program\": \"%s\"\n",program_hex);
     144             :         }
     145           0 :         if (i < gcd_ptr->number_of_gift_card_records-1)
     146           0 :             printf("    },\n");
     147             :         else
     148           0 :             printf("    }\n");
     149             :     }
     150           0 :     printf("  ]\n");
     151           0 :     printf("}\n");
     152           0 : }
     153             : 
     154           1 : int get_gift_card_value(struct this_gift_card *thisone) {
     155             :         struct gift_card_data *gcd_ptr;
     156             :         struct gift_card_record_data *gcrd_ptr;
     157             :         struct gift_card_amount_change *gcac_ptr;
     158           1 :         int ret_count = 0;
     159             : 
     160           1 :         gcd_ptr = thisone->gift_card_data;
     161           2 :         for(int i=0;i<gcd_ptr->number_of_gift_card_records; i++) {
     162           1 :                 gcrd_ptr = (struct gift_card_record_data *) gcd_ptr->gift_card_record_data[i];
     163           1 :                 if (gcrd_ptr->type_of_record == 1) {
     164           1 :                         gcac_ptr = gcrd_ptr->actual_record;
     165           1 :                         ret_count += gcac_ptr->amount_added;
     166             :                 }       
     167             :         }
     168           1 :         return ret_count;
     169             : }
     170             : 
     171             : 
     172             : 
     173             : /* JAC: input_fd is misleading... It's a FILE type, not a fd */
     174           1 : struct this_gift_card *gift_card_reader(FILE *input_fd) {
     175             : 
     176           1 :         struct this_gift_card *ret_val = malloc(sizeof(struct this_gift_card));
     177             : 
     178             :     void *optr;
     179             :         void *ptr;
     180             : 
     181             :         // Loop to do the whole file
     182           3 :         while (!feof(input_fd)) {
     183             : 
     184             :                 struct gift_card_data *gcd_ptr;
     185             :                 /* JAC: Why aren't return types checked? */
     186           1 :                 fread(&ret_val->num_bytes, 4,1, input_fd);
     187             : 
     188             :                 // Make something the size of the rest and read it in
     189           1 :                 ptr = malloc(ret_val->num_bytes);
     190           1 :                 fread(ptr, ret_val->num_bytes, 1, input_fd);
     191             : 
     192           1 :         optr = ptr-4;
     193             : 
     194           1 :                 gcd_ptr = ret_val->gift_card_data = malloc(sizeof(struct gift_card_data));
     195           1 :                 gcd_ptr->merchant_id = ptr;
     196           1 :                 ptr += 32;      
     197             : //              printf("VD: %d\n",(int)ptr - (int) gcd_ptr->merchant_id);
     198           1 :                 gcd_ptr->customer_id = ptr;
     199           1 :                 ptr += 32;      
     200             :                 /* JAC: Something seems off here... */
     201           1 :                 gcd_ptr->number_of_gift_card_records = *((char *)ptr);
     202           1 :                 ptr += 4;
     203             : 
     204           1 :                 gcd_ptr->gift_card_record_data = (void *)malloc(gcd_ptr->number_of_gift_card_records*sizeof(void*));
     205             : 
     206             :                 // Now ptr points at the gift card recrod data
     207           3 :                 for (int i=0; i<=gcd_ptr->number_of_gift_card_records; i++){
     208             :                         //printf("i: %d\n",i);
     209             :                         struct gift_card_record_data *gcrd_ptr;
     210           2 :                         gcrd_ptr = gcd_ptr->gift_card_record_data[i] = malloc(sizeof(struct gift_card_record_data));
     211             :                         struct gift_card_amount_change *gcac_ptr;
     212           2 :                         gcac_ptr = gcrd_ptr->actual_record = malloc(sizeof(struct gift_card_record_data));
     213             :             struct gift_card_program *gcp_ptr;
     214           2 :                         gcp_ptr = malloc(sizeof(struct gift_card_program));
     215             : 
     216           2 :                         gcrd_ptr->record_size_in_bytes = *((char *)ptr);
     217             :             //printf("rec at %x, %d bytes\n", ptr - optr, gcrd_ptr->record_size_in_bytes); 
     218           2 :                         ptr += 4;       
     219             :                         //printf("record_data: %d\n",gcrd_ptr->record_size_in_bytes);
     220           2 :                         gcrd_ptr->type_of_record = *((char *)ptr);
     221           2 :                         ptr += 4;       
     222             :             //printf("type of rec: %d\n", gcrd_ptr->type_of_record);
     223             : 
     224             :                         // amount change
     225           2 :                         if (gcrd_ptr->type_of_record == 1) {
     226           1 :                                 gcac_ptr->amount_added = *((int*) ptr);
     227           1 :                                 ptr += 4;       
     228             : 
     229             :                                 // don't need a sig if negative
     230             :                                 /* JAC: something seems off here */
     231             :                                 if (gcac_ptr < 0) break;
     232             : 
     233           1 :                                 gcac_ptr->actual_signature = ptr;
     234           1 :                                 ptr+=32;
     235             :                         }
     236             :                         // message
     237           2 :                         if (gcrd_ptr->type_of_record == 2) {
     238           0 :                                 gcrd_ptr->actual_record = ptr;
     239             :                                 // advance by the string size + 1 for nul
     240             :                 // BDG: does not seem right
     241           0 :                                 ptr=ptr+strlen((char *)gcrd_ptr->actual_record)+1;
     242             :                         }
     243             :             // BDG: never seen one of these in the wild
     244             :             // text animatino (BETA)
     245           2 :             if (gcrd_ptr->type_of_record == 3) {
     246           0 :                 gcp_ptr->message = malloc(32);
     247           0 :                 gcp_ptr->program = malloc(256);
     248           0 :                 memcpy(gcp_ptr->message, ptr, 32);
     249           0 :                 ptr+=32;
     250           0 :                 memcpy(gcp_ptr->program, ptr, 256);
     251           0 :                 ptr+=256;
     252           0 :                 gcrd_ptr->actual_record = gcp_ptr;
     253             :             }
     254             :                 }
     255             :         }
     256           1 :         return ret_val;
     257             : }
     258             : 
     259             : // BDG: why not a local variable here?
     260             : struct this_gift_card *thisone;
     261             : 
     262           1 : int main(int argc, char **argv) {
     263             :     // BDG: no argument checking?
     264           1 :         FILE *input_fd = fopen(argv[2],"r");
     265           1 :         thisone = gift_card_reader(input_fd);
     266           1 :         if (argv[1][0] == '1') print_gift_card_info(thisone);
     267           0 :     else if (argv[1][0] == '2') gift_card_json(thisone);
     268             : 
     269           1 :         return 0;
     270             : }

Generated by: LCOV version 1.13