来自 asm 代码的未知变量

逆向工程 拆卸 反编译 堆栈变量 料斗 地址
2021-06-13 00:50:37

在将一些 asm 代码翻译成伪代码的过程中,我发现了两个变量:$rbp-0xb4 和 $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;
}
}

看起来 $rbp-0xb8 是在 parse_cereal 调用之后设置的,但我不知道我应该从哪里取它

这是 parse_cereal 伪代码

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;
   }
}

我正在拆卸的二进制文件位于此处

1个回答

终于我找到了答案。解析结果进入后$rbp-0xdo

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

当输入为 0000:1111:2222:3333:4444:5555:6666:7777 所以$rbp-0xb8(var_b8) 类似于$rbp-0xd0+0x18,只是访问解析字符串部分的偏移量。