Predykaty nieprzejrzyste (ang. opaque predicates)

· Dawid Farbaniec

ethical.blue Magazine NaN. Anomalie i zniekształcenia

Predykaty nieprzejrzyste (ang. opaque predicates)

Zniekształcenie z założenia zmienia kod w taki sposób, aby pozostał on semantycznie równoważny. Oznacza to, że zachowuje on swoją funkcjonalność oraz dla tych samych danych wejściowych zwraca identyczne wyniki.

Predykaty nieprzejrzyste to zniekształcenia kontroli przepływu wykonania programu. Implementowane są jako funkcje lub reguły matematyczne, których wynik jest trudny do określenia podczas analizy statycznej.

Podstawowe rodzaje predykatów nieprzejrzystych są następujące. [1]

  • PT — zawsze zwracają wartość logiczną prawda.
  • PF — zawsze zwracają wartość logiczną fałsz.
  • P? — dynamiczne, zwracają wartość logiczną zależną od innych elementów kodu programu.

Dodatkowe rozgałęzienia warunkowe wprowadzają niejasność co do tego, który fragment kodu się wykona, a który blok to martwy kod (ang. dead code).

Przykładowy predykat nieprzejrzysty zaprezentowany poniżej wymaga obliczenia funkcji skrótu SHA3-512, aby określić, czy warunek w instrukcji if jest prawdziwy.

// Opaque predicate (C#)
if (SHA3_512.HashData([0xEF]) is [0xC2, ..]) { /*...*/ } else { /*...*/ }

Inny przykład, przedstawiony poniżej, miesza wyrażenia arytmetyczne oraz logiczne.

// Opaque predicate (C#)
if((x & y) * (x | y) + (x & ~y) * (~x & y) == x * y) { /*...*/ } else { /*...*/ }

Predykaty nieprzejrzyste spotykane w anomaliach mogą być naprawdę bardzo nietypowe. Dodatkowo często są one połączone z innymi zniekształceniami.

Wykaz literatury

[1] Christian Collberg, Clark Thomborson & Douglas Low, Manufacturing Cheap, Resilient, and Stealthy Opaque Constructs, 1998.
[2] Microsoft Corporation, microsoft.com/en-us/research/project/z3, 2026.
[3] The MITRE Corporation, d3fend.mitre.org/technique/d3f:FileAnalysis, 2025.