Site Tools


Hotfix release available: 2025-05-14b "Librarian". upgrade now! [56.2] (what's this?)
pacman

Table of Contents

pacman

Analysis

on a un binaire sans info de debug avec addresses statiques

strings nous retourne rien d'interessant

ltrace montre un appel a memcmp

Reversing

la premiere chose qu'on peut faire c'est ouvrir dans gdb et chopper la valeur attendue

la signature de memcmp c'est

int memcmp(const void *s1, const void *s2, size_t n);

et en gros sur x86_64 les registres deviennent

rdi = s1
rsi = s2
rdx = n

donc on va garder nos deux valeurs au cas ou

Ghidra

ok maintenant on va ouvrir dans ghidra voir ce qui se passe

vu qu'on a pas les infos de debug on va se fier au entry trouve par ghidra

apres renomage d'un peu de fonctions (avec GhidraMCP on va pas mentir) on a un truc du genre

/* WARNING: Restarted to delay deadcode elimination for space: stack */
 
void entry(undefined8 param_1,undefined8 param_2,undefined8 param_3)
 
{
  transform_and_check(exit_or_abort,0x2f4,&DAT_004041db);
  exit_or_abort(param_1,param_2,param_3);
  return;
}

dans transform and check on a

void transform_and_check(void)
 
{
  encrypt_loop();
  bit_rotate_buffer();
  xor_and_subtract_buffer();
  return;
}

dans encrypt loop

void encrypt_loop(int *data_buffer,ulong buffer_length)
 
{
  undefined1 auVar1 [16];
  int round_result;
  long lVar2;
  ulong uVar3;
 
  buffer_length = buffer_length / 4;
  auVar1._8_8_ = 0;
  auVar1._0_8_ = buffer_length;
  lVar2 = SUB168((ZEXT816(0) << 0x40 | ZEXT816(0x34)) / auVar1,0) + 6;
  uVar3 = buffer_length;
  do {
    while (uVar3 = uVar3 - 1, uVar3 != 0) {
      round_result = encrypt();
      data_buffer[uVar3] = data_buffer[uVar3] - round_result;
    }
    round_result = encrypt();
    *data_buffer = *data_buffer - round_result;
    lVar2 = lVar2 + -1;
    uVar3 = buffer_length;
  } while (lVar2 != 0);
  return;
}

encrypt

ulong encrypt(undefined8 param_1,undefined8 param_2,long key_ptr,undefined8 param_4,ulong v0,
             ulong v1)
 
{
  ulong in_R10;
  ulong in_R11;
  ulong unaff_R13;
 
  return (v0 << 2 ^ v1 >> 5) + (v0 >> 3 ^ v1 << 4) ^
         (in_R10 ^ v0) + (*(uint *)(key_ptr + (in_R11 & 3 ^ unaff_R13) * 4) ^ v1);
}

bit rotate

void bit_rotate_buffer(byte *byte_buffer,long buffer_length)
 
{
  byte *pbVar1;
 
  pbVar1 = byte_buffer + buffer_length;
  do {
    *byte_buffer = *byte_buffer >> 3 | *byte_buffer << 5;
    byte_buffer = byte_buffer + 1;
  } while (byte_buffer != pbVar1);
  return;
}

xor and sub

void xor_and_subtract_buffer(byte *byte_buffer,long buffer_length)
 
{
  byte *pbVar1;
 
  pbVar1 = byte_buffer + buffer_length;
  do {
    *byte_buffer = *byte_buffer - 0x37;
    *byte_buffer = *byte_buffer ^ 0xaa;
    byte_buffer = byte_buffer + 1;
  } while (byte_buffer != pbVar1);
  return;
}

du coup a ce stade l'idee c'est de reimplementer ca de notre cote, voir si quand on passe notre input de 11111[…] on obtient la meme valeur que la reference et si c'est le cas, implementer l'algo d'encryption en reverse…

pacman.txt · Last modified: by 86.247.56.28