Povratni inžiniring »Reverse Engineering«

28.07.2026

Povratno inženirstvo je ključen analitičen proces za razumevanje delovanja programske opreme v primerih, ko originalna izvorna koda ni na voljo. V tem članku boste spoznali celoten cikel pretvorbe programske kode v asamblerski ter strojni zapis in postopek njene rekonstrukcije z uporabo dekompilatorja. Prav tako boste odkrili, zakaj zaradi optimizacije prevajalnika povsem natančna obnova izvirnega zapisa ni mogoča, čeprav je osnovno delovanje programa mogoče uspešno poustvariti.

Povratno inženirstvo je proces analiziranja prevedenega programa z namenom razumevanja njegovega delovanja, kadar izvorna koda ni na voljo. Pogosto se uporablja za analizo programske opreme, raziskovanje zlonamerne kode, odkrivanje ranljivosti ter pridobivanje informacij iz starejših aplikacij.

Primer izvorne kode v jeziku C++

#include <fmt/core.h>
#include "io.h"
#include <iostream>

int main() {
    // komentar
    int a = 3, b = 1;

    a += b;

    std::cout << a;

    return 0;
}
Izvorna koda se najprej prevede v asamblerske ukaze, ki predstavljajo človeku berljive operacije procesorja. Ti ukazi se nato pretvorijo v strojno kodo (binarno obliko), ki jo procesor lahko neposredno izvaja. Med tem postopkom se odstranijo komentarji, oblikovanje kode in številna izvirna imena spremenljivk.

Asambler z razlago

- sub rsp,0x8 -> Rezervira 8 bajtov prostora za potrebe funkcije.
-  mov esi,0x4 -> Premakne število 4 v register ESI. Prevajalnik je med optimizacijo že vnaprej izračunal izraz 3 + 1.
-  mov edi,0x404040 -> Premakne pomnilniški naslov objekta std::cout v register EDI.
-  call 401030 <std::ostream::operator<<(int)@plt> -> Pokliče funkcijo standardne knjižnice, ki izpiše celo število na konzolo.
-  xor eax,eax -> Nastavi register EAX na 0, kar predstavlja povratno vrednost funkcije.
-  add rsp,0x8 -> Obnovi kazalec sklada in sprosti prej rezerviranih 8 bajtov.
-  ret -> Vrne se iz funkcije, kar je enakovredno ukazu return 0;.
-  nop WORD PTR [rax+rax*1+0x0] -> Ukaz »No Operation« (brez operacije), uporabljen za poravnavo kode v pomnilniku. Ne vpliva na samo izvajanje programa.

Heksadecimalna koda v binarno kodo

48 83 EC 08 -> 01001000 10000011 11101100 00001000
BE 04 00 00 00 -> 10111110 00000100 00000000 00000000 00000000
BF 40 40 40 00 -> 10111111 01000000 01000000 01000000 00000000
E8 DD FF FF FF -> 11101000 11011101 11111111 11111111 11111111
31 C0 -> 00110001 11000000
48 83 C4 08 -> 01001000 10000011 11000100 00001000
C3 -> 11000011
66 0F 1F 44 00 00 -> 01100110 00001111 00011111 01000100 00000000 00000000
Ta binarna koda je težko razumljiva, vendar predstavlja natančne strojne ukaze, ki jih izvaja procesor.
Za izvedbo obratnega inženirstva analitik običajno najprej pretvori strojno kodo nazaj v asamblerski jezik (disassembly), nato pa uporabi dekompilator, da rekonstruira predstavitev programa v višje nivojskem programskem jeziku.

Dekompiliran izpis

Z uporabo dekompilatorja lahko asamblersko kodo pretvorimo nazaj v izvorno kodo, podobno jeziku C:
int main(void)
{
    std::cout << 4;
    return 0;
}
Dekompilirana koda je po svojem delovanju enakovredna izvirnemu programu, kljub temu pa se med prevajanjem izgubi večina podrobnosti. Izvirni deklaraciji in operacija:
int a = 3, b = 1;
a += b;
sta bili med optimizacijo združeni v konstantno vrednost 4. Zaradi tega dekompilator ne prikaže več spremenljivk a in b, saj v končni strojni kodi fizično ne obstajata več. Prav tako v izpisu ni vključenih knjižnic, originalnega oblikovanja in komentarjev. Kot lahko opazimo, komentar »// comment« ni prisoten niti v asamblerju niti v dekompilirani kodi.
Glede na nastavitve prevajalnika in stopnjo optimizacije lahko različni dekompilatorji ustvarijo nekoliko drugačen izpis, na primer:
undefined8 main(void)
{
    std::ostream::operator<<(std::cout,4);
    return 0;
}
Čeprav je ta različica vizualno drugačna od izvirne kode, izvaja popolnoma enake operacije. Rekonstruirati delovanje programa je običajno mogoče, natančno poustvariti prvotno izvorno kodo pa praviloma ne.

Žiga Brinc
Front - end programer III
ziga.brinc@kompas-xnet.si

Imate dodatna vprašanja?

Za več informacij smo vam vedno z veseljem na voljo. Pišite nam na info@kompas-xnet.si ali nas pokličite 01 5136 990.

Kontaktirajte nas

Novice

Naročite se na Xnet novice in ostanite na tekočem glede novih tečajev, seminarjev, možnosti pridobitve novih certificiranj in akcijskih cen.

Katero področje novic vas zanima?

Potrebuješ pomoč? bot icon
Potrebuješ pomoč?