这个 ghidra 生成的伪 C 代码生成了什么?

what does this ghidra-generated pseudo c-code generate?

我正在尝试使用 ghidra 进行逆向工程的一些挑战。

我分析了一个bin文件,里面应该有一些关于密码的信息。 当你 运行 文件时,你可以给它一些输入,它会检查它是否是正确的密码。 这是负责执行此操作的伪 C 代码(评论是我):

  __isoc99_scanf(&DAT_00400a82,local_28); // input scanned from user
  __s2 = (char *)FUN_0040078d(0x14); // password retrieved from function
  iVar1 = strcmp(local_28,__s2); // comparing strings
  if (iVar1 == 0) { // if they are equal, do this
    FUN_00400978(&local_48);
  }

好的,所以我尝试查找函数 FUN_0040078d:

void * FUN_0040078d(int param_1)

{
  int iVar1;
  time_t tVar2;
  void *pvVar3;
  int local_c;
  
  tVar2 = time((time_t *)0x0);
  DAT_00601074 = DAT_00601074 + 1;
  srand(DAT_00601074 + (int)tVar2 * param_1);
  pvVar3 = malloc((long)(param_1 + 1));
  if (pvVar3 != (void *)0x0) {
    local_c = 0;
    while (local_c < param_1) {
      iVar1 = rand();
      *(char *)((long)local_c + (long)pvVar3) = (char)(iVar1 % 0x5e) + '!';
      local_c = local_c + 1;
    }
    *(undefined *)((long)pvVar3 + (long)param_1) = 0;
    return pvVar3;
  }
                    /* WARNING: Subroutine does not return */
  exit(1);
}

所以这里有很多信息。但总的来说,我认为发生的是通过执行以下操作构造了一个字符数组:

(char)(iVar1 % 0x5e) + '!';

我不知道这是什么意思(对字符取模是做什么的?+ '!' )只是表示连接一个“!”。

总的来说,我在阅读这篇文章时遇到了一些问题,我想知道是否有可能预测这个函数针对特定输入会输出什么。在这种情况下,函数被赋予 14 作为输入。

也许使用rand()意味着不能解构?

谁能告诉我 guess/tell 这个函数对于输入 14 可能会输出什么?

你必须记住,每个字符都是一个 8 位值的字符表示。因此每个运算符在字符范围内都是有效的。

我做了这个例子是为了让你更好地理解它。

#include <stdio.h>
#include <stdlib.h>


int main(int argc, char **argv) 
{
    char character = 'A'; // 65 in dec
    char bang = '!'; // 33 in dec


    printf("'A' in dec: %d\n", (int)character);
    printf("'!' in dec: %d\n", (int)bang);


    
    // now the modulo operator works the same in chars
    character = 'a';
    char new_value = (char)character%64;
    printf("a %% 64 : char_value: %c, int_value: %d\n", new_value, (int)new_value);
    
    // you got to remember that chars are just a coded 8bit value
    
    char at_symbol = '@'; // 64 in dec

    // now the modulo operator works the same in chars
    character = 'a';
    new_value = (char)character%at_symbol;
    printf("a %% @ : char_value: %c, int_value: %d\n", new_value, (int)new_value);


    // it works the same with every other operator 
    

    
    int value1 = 300; //this is your random value

    char hex_value = 0x5E; //94 in dec or ^ in char

    new_value = (char)(value1%hex_value); //300 % 94 = 18;

    new_value += bang; //18 + 33 = 51 in dec or the number 3 symbol in char;

    printf("dec_val: %d, char encoding: %c\n", (int)new_value, new_value);


}

根据您之前的评论,这是您函数的简化版本

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

long GLOBAL_COUNTER = 0;

typedef char undefined;

void * array_constructor(int size);

int main(int argc, char **argv) 
{

    char* random_string = (char*)array_constructor(0x14);
    printf("%s", random_string);
    free(random_string);
}


void * array_constructor(int size)
{
    int random_value;
    //time_t cur_time;
    void *array;
    int counter;

    //cur_time = time(NULL);
    GLOBAL_COUNTER = GLOBAL_COUNTER + 1;
    srand(0);//srand(GLOBAL_COUNTER + (int)cur_time * param_1);
    array = malloc((long)(size + 1));//returns a void array of param_1 + 1 elements 
    if (array == NULL) 
      exit(1);
    
    counter = 0;
    while (counter < size) {
    random_value = rand();
    int char_value = (char)(random_value % 0x5e) + '!';//Range of possible values 33-127
    // This is due to the fact that random value can have any value given the seed
    // but its truncated to a modulo 0x5e so its new range is 0 - 0x5e(94 in dec) 
    // and you add the bang symbol at the end so 0 + 33 = 33 and 94 + 33 = 127 

    *(char *)((long)counter + (long)array) = char_value;    
    // this statement is the same as
    // array[counter] = char_value
    counter++;
    }
    *(undefined *)((long)array + (long)size) = 0; //it puts the [=10=] at the end of the string
    return array;
}

现在您遇到的唯一问题是未定义的 typedef。此代码是您的简化版。但它有效。