2

During translating some asm code into pseudocode I've found two variables: $rbp-0xb4 and $rbp-0xb8

function check_password(arg0) {
   var_18 = *0x28; //stack checksum?
   if (parse_cereal(var_D0, arg0) == 0){
   //var_B8, var_B4 from where?
     if (var_B8 > 0){
        print_cereal(var_D0);
        for (var_E4 = 0; var_E4 <= 7; var_E4++) {
          rbp[var_E4 * 2 - 0xe0][0:2] = rbp[var_E4 * 4 - 0xd0][0:2];//2 lower bytes
        }
        for (var_E4 = var_B4 + var_B8; var_E4 > 0; var_E4--) {
           MD5_Init(MD5instance);
           MD5_Update(MD5instance, var_E0, 16);
           MD5_Final(var_E0, MD5instance); //var_B0 = MD5instance
        } //var_B8+var_B4 should be <= 0
        //var_B8 > 0, => var_B4 should be <= -var_B8
        var_E4 = 0;
        for(var_E4=0;var_E4 <= 5;var_E4++){
           if not(rbp[var_E4 * 2 - 0xe0][0:2] == rbp[var_E4 * 4 - 0xd0][0:2])//2 lower bytes 
           {
             rax = 0xffffffff;
             rbx = var_18 ^ *0x28;
             if (rbx != 0x0) {
             rax = __stack_chk_fail();
             }
             return rax;
           }
        }
        else{
          rax = 0x0;

          rbx = var_18 ^ *0x28;
          if (rbx != 0x0) {
             rax = __stack_chk_fail();
          }//stack check
          return rax;
        }
     }
     else{
        puts("I can't take any risks with you. The counter at the end must be larger than 0000+XXXX.");
        rax = 0xffffffff;
        rbx = var_18 ^ *0x28;
        if (rbx != 0x0) {
           rax = __stack_chk_fail();
        }
        return rax;
     }

}
else
{
   puts("That's not a cereal box. Cereals are a bit like ipv6s but LESS COMPLICATED.");
   rax = 0xffffffff;
   rbx = var_18 ^ *0x28;
   if (rbx != 0x0) {
     rax = __stack_chk_fail();
   }
   return rax;
}
}

Looks like $rbp-0xb8 is set after parse_cereal call, but I don't know from where should I take it

And here is parse_cereal pseudocode

function parse_cereal(arg0, arg1){ //arg1 - string to parse, arg0 where to parse 
   if(strlen(arg1)==39){
      for(var_8=0;var_8<=0x26;var_8++){
      if (((arg1[var_8] <= 0x2f) || (arg1[var_8] > 0x39)){
           if ((arg1[var_8] <= 0x60) || (arg1[var_8] > 0x66)){
             if ((arg1[var_8] <= 0x40) || (arg1[var_8] > 0x46)){
               if (arg1[var_8] != 0x3a){
                  rax = 0xffffffff;
                  return rax;
               }
             }
           }
      }
      }
      //check symbols range '0-9' ':' 'a-f' 'A-F'
      for(var_8=0;var_8<=7;var_8++){//0,1,
     arg0[var_8*4] = 0; //arg0 = var_18
     for (var_4 = 5*var_8; 4 + 5*var_8 > var_4; var_4++) {
          rdx = arg0[var_8*4];//always zero at first iteration, 4 bytes
          rsi = arg0[var_8*4] * 16;
          rsi += UppercaseToLowercase(arg1[var_4]);//rsi += lower(arg[1])
          if (arg1[var_4] <= 0x39) {
            rax = 0x30;//set '0123456789' to 0
          }
          else {
            rax = 0x57; //set other symbols to 'W'
          }
          rdx = rsi - rax;//arg0[var_8*4]=(arg0[var_8*4]*16+lower(arg1[var_4]))-rax?
     }
     //proceed 4 bytes
     if not ((var_8 >= 7) || (arg1[var_4] == 0x3a)){ //check if arg1[i](i=5,10,15,20,25,30,35) is ':'
        rax = 0xffffff;
        return rax;
     }
      }
      rax = 0;
      return rax;
   }
   else{
      rax = 0xfffff;
      return rax;
   }
}

Binary I'm disassembling located here

2

Finally I've found an answer. After parsing result lies into $rbp-0xdo

(gdb) x/8w ((int*)($rbp-0xd0))
0x7fffffffdf90: 0x00000000      0x00001111      0x00002222      0x00003333
0x7fffffffdfa0: 0x00004444      0x00005555      0x00006666      0x00007777

when input is 0000:1111:2222:3333:4444:5555:6666:7777 So $rbp-0xb8 (var_b8) is similar to $rbp-0xd0+0x18, just an offset to access part of parsed string.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.