Объяснение указателя Ghidra (ELI не знает о C / C ++) - PullRequest
0 голосов
/ 07 августа 2020

Учитывая, что param_1 - это байты входного файла, может ли кто-нибудь объяснить, что делает uVar4 = *(uint *)(param_1 + 3)? Преобразование param_1 в uint, а затем uVar4 = param_1[3]? Также любые разъяснения по поводу указателя тоже хороши b c мой опыт работы с C / Cpp близок к нулю (даже не говоря уже об указателях)

uchar * DecryptLZ4(uchar *param_1,ulong param_2,ulong *param_3) //param_1: file bytes, param_2: file size

{
  uchar uVar1;
  uchar *puVar2;
  int iVar3;
  uint uVar4;
  bool bVar5;
  ulong local_28;
  int local_24;
  
  local_24 = __stack_chk_guard;
  local_28 = param_2;
  if (((param_1 != (uchar *)0x0) && (6 < param_2)) && (*param_1 == -8)) { //if param_1[0] == 0xf8..
    uVar1 = param_1[1];
    bVar5 = uVar1 == -0x75; // ..and param_1[1] == 0x8b:
    if (bVar5) { 
      uVar1 = param_1[2];
    } // if param_1[0] = 
    if (((bVar5 && uVar1 == '+') && (param_2 != 7)) && //if param_1[2] == 0x2b and param_2 != 7
       (uVar4 = *(uint *)(param_1 + 3), uVar4 < 0x2000001)) { // THIS LINE
      puVar2 = (uchar *)Allocate((int)GlobalAllocator,(char *)(uVar4 + 1),
                                 (int)
                                 "XANA"
                                 ,&DAT_00000085);
      if (puVar2 != (uchar *)0x0) {
        iVar3 = FUN_00298230(param_1 + 7,puVar2,param_2 - 7,uVar4);
        if (iVar3 < 1) {
          Free((BlockAllocator *)GlobalAllocator,puVar2,(int)(char *)(uVar4 + 1));
          goto LAB_00346faa;
        }
        puVar2[iVar3] = '\0';
        Free((BlockAllocator *)GlobalAllocator,param_1,local_28 + 1);
        param_2 = uVar4;
        param_1 = puVar2;
        local_28 = uVar4;
      }
      if ((0 < (int)uVar4) && (2 < param_2)) {
        while (*param_1 == -8) {
          uVar1 = param_1[1];
          bVar5 = uVar1 != -0x75;
          if (!bVar5) {
            uVar1 = param_1[2];
          }
          if ((bVar5 || uVar1 != '+') ||
             (param_1 = (uchar *)DecryptLZ4(param_1,param_2,&local_28), param_2 = local_28,
             local_28 < 3)) break;
        }
      }
    }
  }
LAB_00346faa:
  if (param_3 != (ulong *)0x0) {
    *param_3 = param_2;
  }
  if (__stack_chk_guard == local_24) {
    return param_1;
  }
                    /* WARNING: Subroutine does not return */
  __stack_chk_fail();
}

1 Ответ

0 голосов
/ 07 августа 2020

Вы должны смотреть на круглые скобки.

В uVar4 = *(uint *)(param_1 + 3) сложение происходит перед преобразованием в указатель на uint. param_1 имеет тип uchar *.

Итак, это не похоже на uVar4 = param_1[3], потому что выражение param_1[3] имеет тип uchar. Эта версия будет загружать только один байт, расширенный (предположительно) до 4 байтов для хранения в uVar4. Оригинал скопирует (предположительно) 4 байта с адреса param_1 + 3 на uVar4.

Мой ответ на

Это приведение param_1 к uint, тогда uVar4 = param_1 [3]

будет нет по двум причинам:

  • param_1 имеет фиксированный тип (uchar *), преобразование не меняет его тип.
  • Если бы вы сделали что-то вроде uint *param_2_ui = (uint *) param_1, то uVar4 = param_2_ui [3] результат был бы другим .

В C (и C ++, хотя это совершенно другой язык) добавление к указателям добавит к адресу размера указанного типа.

На практике, предполагая, что sizeof(int) == 4, и учитывая это:

int tmp[2];
int *ptr1 = tmp;

Выражение ptr1 + 1 будет представлять адрес 4 больше, чем ptr1.

...