rev2_ghidra
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| rev2_ghidra [2025/10/30 15:28] – mbunic | rev2_ghidra [2025/12/01 11:40] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ==== rev2 ==== | ==== rev2 ==== | ||
| - | Uz zadatak je dana samo izvršna datoteka " | + | Uz zadatak je dana samo izvršna datoteka " |
| + | Pokretanjem programa, traži se lozinka i nakon unosa, ispisuje se poruka o pogrešnoj lozinki. | ||
| - | Pokretanjem programa, program nas pita za password i ispisuje krivi password, pri unosu netočnog passworda. | + | {{ rev2_ghidra: |
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | Slika 1. pokretanje programa | + | |
| - | + | ||
| - | {{ : | + | |
| Može se pokrenuti naredba file kako bi se saznale osnovne informacije o programu. | Može se pokrenuti naredba file kako bi se saznale osnovne informacije o programu. | ||
| Line 20: | Line 13: | ||
| </ | </ | ||
| - | slika 2. rezultat file naredbe | + | {{ rev2_ghidra: |
| - | {{ :slika2.png? | + | Program je statically linked, zato se može samostalno pokretati. Također je stripped, zato imena varijabli i funkcija neće biti sačuvane, što će malo otežati reverzno inženjerstvo nad programom. |
| - | Program je statically liked, znači da se može samostalno pokretati. Također je stripped, što znači da imena varijabli i funkcija neće biti sačuvane, što će malo otežati reverzno inženjerstvo nad programom. | + | Nakon toga se može pokrenuti naredba strings da se vidi ima li zanimljivih stringova u datoteci. |
| - | + | ||
| - | + | ||
| - | Nakon toga se može pokrenuti naredba, strings da se vidi ima li zanimljivih stringova u datoteci. | + | |
| < | < | ||
| Line 33: | Line 23: | ||
| </ | </ | ||
| - | No ni jedan vraćeni rezultat ne izgleda kao da previše otkriva. Može se također odmah pretražiti | + | No niti jedan vraćeni rezultat ne izgleda kao da previše otkriva. Može se također odmah pretražiti |
| < | < | ||
| Line 39: | Line 29: | ||
| </ | </ | ||
| - | zastavica " | + | zastavica " |
| - | + | ||
| - | slika 3. rezultat strings naredbe | + | |
| - | + | ||
| - | {{ : | + | |
| - | Ovo nam također ništa | + | {{ rev2_ghidra: |
| + | Ovo nam također ništa korisno ne otkriva o programu, osim što prikazuje tekst koji se ispisuje pri unosu passworda i ispisu pri krivom unosu passworda. | ||
| Nakon toga se može probati naredba " | Nakon toga se može probati naredba " | ||
| Line 54: | Line 41: | ||
| </ | </ | ||
| + | {{ rev2_ghidra: | ||
| - | Slika 4. - rezultat strace naredbe | + | Također se na prvi pogled ne mogu pronaći dodatne korisne informacije o programu u ispisu. |
| - | {{ :slika4.png? | + | Sljedeći korak je korištenje besplatnog Ghidra alata za reverzno inženjerstvo nad programom (ako niste upoznati s alatom, pogledajte materijale o ovom alatu na poveznici - https://www.cert.hr/wp-content/ |
| - | Također se ne prvi pogled ne mogu pronaći dodatne korisne informacije o programu u ispisu. | + | {{ rev2_ghidra: |
| - | + | ||
| - | Slijedeći korak je korištenje besplatnog Ghidra softwarea za reverzno inženjerstvo nad programom (ako niste upoznati s alatom, pogledajte materijale o ovom alatu također dostupne na wiki stranicama na linku- | + | |
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | Slika 5. Ghidra alat | + | |
| - | + | ||
| - | {{ : | + | |
| Dvoklikom na rev2 datoteku u sučelju, otvara se sučelje za pregled dekompajliranog koda programa. | Dvoklikom na rev2 datoteku u sučelju, otvara se sučelje za pregled dekompajliranog koda programa. | ||
| - | + | {{ rev2_ghidra: | |
| - | + | ||
| - | + | ||
| - | + | ||
| - | Slika 6. sučelje za analizu koda i bitni dijelovi | + | |
| - | + | ||
| - | {{ : | + | |
| Na slici vidimo entry point, dio koda koji se prvi izvršava pri pokretanju programa, u Decompile sučelju vidi se da entry point funkcija samo poziva funkciju " | Na slici vidimo entry point, dio koda koji se prvi izvršava pri pokretanju programa, u Decompile sučelju vidi se da entry point funkcija samo poziva funkciju " | ||
| - | + | {{ rev2_ghidra: | |
| - | + | ||
| - | + | ||
| - | + | ||
| - | Slika 7. pregled funkcije | + | |
| - | + | ||
| - | {{ : | + | |
| Pregledom dekompajliranog koda ove funkcije, može se zaključiti da je ovo main funkcija, vidi se dio koda koji ispisuje "Enter password: ", i dio koda odmah ispod, koji bi mogao biti fgets funkcija za čitanje korisničkog unosa, koji zatim sprema na varijablu pbVar5. | Pregledom dekompajliranog koda ove funkcije, može se zaključiti da je ovo main funkcija, vidi se dio koda koji ispisuje "Enter password: ", i dio koda odmah ispod, koji bi mogao biti fgets funkcija za čitanje korisničkog unosa, koji zatim sprema na varijablu pbVar5. | ||
| Line 98: | Line 65: | ||
| </ | </ | ||
| - | Na početku main funkcije, | + | Na početku main funkcije, |
| < | < | ||
| Line 110: | Line 77: | ||
| </ | </ | ||
| - | također, vidi se da je drugi argument poziva funkcije | + | također, vidi se da je drugi argument poziva funkcije |
| - | + | ||
| Treći argument je pointer | Treći argument je pointer | ||
| - | + | {{ rev2_ghidra: | |
| - | + | ||
| - | Slika 8. vrijednost na koju pointer | + | |
| - | + | ||
| - | {{ : | + | |
| vrijednost je | vrijednost je | ||
| Line 129: | Line 90: | ||
| Prva 4 bajta FBAD su "magic number" | Prva 4 bajta FBAD su "magic number" | ||
| - | |||
| Sada znamo da bi ova linija | Sada znamo da bi ova linija | ||
| Line 137: | Line 97: | ||
| </ | </ | ||
| - | odgovarala | + | odgovarala |
| < | < | ||
| Line 143: | Line 103: | ||
| </ | </ | ||
| + | Može se označiti varijabla local_118, pritisnuti gumb L i preimenovati u input_buffer. | ||
| + | {{ rev2_ghidra: | ||
| + | Također se varijabla pbVar5 može preimenovati u user_input, PTR_DAT_004aa6d8 u stdin i | ||
| + | FUN_00404ee0 u fgets. Varijablu lVar2 nećemo preimenovati, | ||
| - | Sad se može označiti | + | Kako bi se olakšalo praćenje važnih varijabli, varijable koje su bitne u izvođenju programa mogu se označiti i pritiskom desnog klika i opcije highlight, mogu se postaviti da budu istaknuto označenu ostatku programa. |
| - | + | fgets funkcija pri uspješnom izvršavanju vraća pointer na string buffer, a ako je vraćena vrijednost NULL, dogodila se greška, što odgovara ovom dijelu | |
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | Slika 9. Preimenovanje varijable u Ghidri | + | |
| - | + | ||
| - | {{ : | + | |
| - | + | ||
| - | Također se varijable pbVar5 može preimenovati u user_input, PTR_DAT_004aa6d8 u stdin i | + | |
| - | FUN_00404ee0 u fgets. Varijablu lVar2 nećemo preimenovati, | + | |
| - | + | ||
| - | Kako bi se olakšalo praćenje važnih varijabli, varijable koje su bitne u izvođenju programa mogu se označiti i pritiskom desnog klika i opcije highlight, mogu se postaviti da budu bolje naznačenje u ostatku programa. | + | |
| - | + | ||
| - | fgets funkcija pri uspješnom izvršavanju, vraća pointer na string buffer, a ako je vraćena vrijednost NULL, dogodila se greška, što odgovara ovom djelu koda | + | |
| < | < | ||
| Line 181: | Line 122: | ||
| </ | </ | ||
| - | Ako je fgets vratio NULL, varijabla uVar3 se postavlja u 1 i skače se na kraj main funkcije, te se varijabla uVar3 vrača kao return vrijednost main funkcije, | + | Ako je fgets vratio NULL, varijabla uVar3 se postavlja u 1 i skače se na kraj main funkcije, te se varijabla uVar3 vraća kao return vrijednost main funkcije, |
| - | + | ||
| - | + | ||
| - | Ako se fgets uspješno izvršio, izvršava se else block, koji počinje ovim kodom | + | |
| + | Ako se fgets uspješno izvršio, izvršava se else blok, koji počinje ovim kodom | ||
| < | < | ||
| Line 198: | Line 136: | ||
| dvoklikom na adresu DAT_0047f021 na kojoj je vrijednost drugog argumenta proslijeđenog ovoj funkciji, može se vidjeti vrijednost na toj adresi | dvoklikom na adresu DAT_0047f021 na kojoj je vrijednost drugog argumenta proslijeđenog ovoj funkciji, može se vidjeti vrijednost na toj adresi | ||
| - | + | {{ rev2_ghidra: | |
| - | + | ||
| - | Slika 10. vrijednost na adresi | + | |
| - | + | ||
| - | {{ : | + | |
| Vrijednost je " | Vrijednost je " | ||
| - | + | Može se zaključiti da funkcija thunk_FUN_00412860 vjerojatno vraća poziciju | |
| - | Može se zaključiti da funkcija thunk_FUN_00412860 vjerojatno vraća poziciju na kojoj se u korisničkom unosu nalazi CR LF, odnosno kraj unosa. | + | |
| < | < | ||
| Line 217: | Line 150: | ||
| U tom slučaju bi varijabla | U tom slučaju bi varijabla | ||
| - | Nakon toga, u if statementu, vrijednost varijable | + | Nakon toga, u if statementu, vrijednost varijable lVar2 se uspoređuje s 0x15, odnosno 21 u dekadskom zapisu, što točno odgovara duljini FLAG formata |
| < | < | ||
| Line 223: | Line 156: | ||
| </ | </ | ||
| + | Ako je duljina korisničkog unosa jednaka 21, ulazi se u do - while blok, unutar kojega se nalazi switch sa 7 caseva. Ako uvjet nije zadovoljen, skače se na funkciju koja ispisuje "Wrong password!" | ||
| - | Ako je duljina korisničkog jednaka 21, ulazi se u do - while block, unutar kojega se nalazi switch sa 7 caseva, ako nije skače se na funkciju koja ispisuje "wrong password", | + | Pregledom switcha, na kraju switcha se odmah može vidjeti case 0, koji samo ispisuje |
| - | + | ||
| - | Pregledom switcha, na kraju switcha se odmah može vidjeti case 0, koji samo ispisuje | + | |
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | Slika 11. Switch case 0 | + | |
| - | {{ : | + | {{ rev2_ghidra: |
| - | Na početku do blocka, se nalazi ova linija | + | Na početku do bloka, se nalazi ova linija |
| < | < | ||
| Line 244: | Line 168: | ||
| </ | </ | ||
| - | koja postavlja varijablu bVar1 na dereferenciranu vrijednost user_input pointera, koji je pointer na string buffer. | + | koja postavlja varijablu bVar1 na dereferenciranu vrijednost user_input pointera, koji je pointer na string buffer. |
| - | može preimenovati u user_input_char. | + | |
| - | U switchu postoji 7 caseva, a case se određuje prema vrijednosti puVar2. | + | U switchu postoji 7 caseva, a case se određuje prema vrijednosti |
| - | + | ||
| - | + | ||
| - | Slika 12. - switch value | + | |
| - | + | ||
| - | {{ : | + | |
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | Slika 13. -switch | + | |
| - | + | ||
| - | {{ : | + | |
| + | {{ rev2_ghidra: | ||
| + | {{ rev2_ghidra: | ||
| Vidi se da se u svakom caseu uzima user_input_char, | Vidi se da se u svakom caseu uzima user_input_char, | ||
| - | + | u caseu 1 operacija je XOR (^), u caseu 2 operacije je ADD (+) u caseu 3 operacije je SUB (-), u caseu 4 operacije je MUL (*), u caseu 5 operacija je bitwise SHIFT (<< i >>), u caseu 6 operacija je bitwise NOT (~) i u caseu 7 operacije je također ADD (+), kao što je prethodno opisano. | |
| - | u case 1 operacija je XOR (^), u case 2 operacije je ADD (+) u case 3 operacije je SUB (-), u case 4 operacije je MUL (*), u case 5 operacija je bitwise SHIFT (<< i >>), u case 6 operacija je bitwise NOT (~) i u case 7 operacije je također ADD (+), kao što je prethodno opisano. | + | |
| - | + | ||
| - | + | ||
| odlaskom na adresu gdje je Stack[-0x158] i dvoklikom na XREF[3,12] | odlaskom na adresu gdje je Stack[-0x158] i dvoklikom na XREF[3,12] | ||
| - | + | {{ rev2_ghidra: | |
| - | + | ||
| - | Slika 14. Stack[-0x158] | + | |
| - | + | ||
| - | {{ : | + | |
| Također možemo vidjeti opis switch caseva, koji je upravo bio opisan. | Također možemo vidjeti opis switch caseva, koji je upravo bio opisan. | ||
| - | + | {{ rev2_ghidra: | |
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | Slika 15. switch caseovi. | + | |
| - | + | ||
| - | {{ : | + | |
| Još je preostalo pronaći što je varijabla koja određuje koji switch case će biti odabran, operandi u switch caseovima i očekivani rezultati operacija, koji su svi određeni u varijabli puVar2. | Još je preostalo pronaći što je varijabla koja određuje koji switch case će biti odabran, operandi u switch caseovima i očekivani rezultati operacija, koji su svi određeni u varijabli puVar2. | ||
| + | Varijabla puVar2 je definirana pri početku programa i pokazuje na adresu varijable local_158, koja sadržava hex vrijednosti. | ||
| - | Varijabla | + | {{ rev2_ghidra: |
| + | Budući da je program stripped, moguće je da je Ghidra krivo rekonstruirala ove varijable, ne njihove vrijednosti, | ||
| + | Na samom kraju do bloka, nakon switcha casea-7, se user_input pointer povećava za 1, tako će se za sljedeću iteraciju do bloka koristiti sljedeći character iz user inputa. | ||
| - | + | početak do bloka | |
| - | + | ||
| - | Slika 16. - puVar2 | + | |
| - | i local_158 | + | |
| - | + | ||
| - | {{ : | + | |
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | No pošto je program stripped, moguće je da je Ghdira krivo rekonstruirala ove varijable, ne njihove vrijednosti nego kako su definirane, varijable nakon local_158 se ne spominju dalje u main funkciji, a nalaze se odmah ispod local_158 na koju pokazuje puVar2. | + | |
| - | + | ||
| - | Na samoj kraju do blocka, nakon switcha casea-7, se user_input pointer povećava za 1, znači da se za sljedeću iteraciju do blocka koristiti slijedeći character iz user inputa | + | |
| - | + | ||
| - | + | ||
| - | početak do blocka | + | |
| < | < | ||
| Line 325: | Line 204: | ||
| </ | </ | ||
| - | a puVar2 se povećava za 3 u svakoj iteraciji, što taman odgovara 3 vrijednosti koje se koriste | + | a puVar2 se povećava za 3 u svakoj iteraciji, što taman odgovara 3 vrijednosti koje se koriste u svakom do bloku, puVar2 + 0 određuje koji switch case će se izvršiti, |
| - | u svakom do blocku, puVar2 + 0 određuje koji switch case će se izvršiti, | + | |
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | Slika 17. inkrementiranje puVar2 i user_input pointera | + | |
| - | {{ : | + | {{ rev2_ghidra: |
| - | Pošto | + | Budući da će se svaki user input character imati jednu vlastitu iteraciju, a puVar2 se povećava za 3 nakon svake iteracije, |
| Ovo se također može vidjeti na slici ispod, while se izvršava sve dok varijabla pbVar2 koja se povećava za 3 nije jednaka adresi spremljenoj na local_119, koja je RSP uvećan za 0x3f, odnosno 63 u dekadskom zapisu, zato što ima 63 byte vrijednosti spremljenih na stacku. | Ovo se također može vidjeti na slici ispod, while se izvršava sve dok varijabla pbVar2 koja se povećava za 3 nije jednaka adresi spremljenoj na local_119, koja je RSP uvećan za 0x3f, odnosno 63 u dekadskom zapisu, zato što ima 63 byte vrijednosti spremljenih na stacku. | ||
| + | {{ rev2_ghidra: | ||
| - | Slika 18. - local_119 | + | Na slici 16. se vidi da je puVar2 pointer na local_158, sada znamo da local_158 zapravo sadržava 63 bajtova |
| - | + | ||
| - | {{ : | + | |
| - | + | ||
| - | Na slici 15. se vidi da je puVar2 pointer na local_158, sada znamo da local_158 zapravo sadržava 63 byteova, | + | |
| - | + | ||
| - | + | ||
| - | + | ||
| - | Slika 19 - retype local_158 | + | |
| - | + | ||
| - | {{ : | + | |
| - | + | ||
| - | + | ||
| + | {{ rev2_ghidra: | ||
| Znamo da sadržava byte vrijednost i duljine je 63, pa type možemo postaviti u | Znamo da sadržava byte vrijednost i duljine je 63, pa type možemo postaviti u | ||
| Line 365: | Line 223: | ||
| </ | </ | ||
| + | {{ rev2_ghidra: | ||
| - | + | {{ rev2_ghidra:slika21.png? | |
| - | Slika 20 - local_158 byte[63] retype | + | |
| - | + | ||
| - | {{ :slika20.png? | + | |
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | Slika 21. Promijenjeni prikaz local_158 | + | |
| - | + | ||
| - | {{ : | + | |
| Sada je promijenjen prikaz i može se jasno vidjeti da su ovdje zapravo pohranjene vrijednosti: | Sada je promijenjen prikaz i može se jasno vidjeti da su ovdje zapravo pohranjene vrijednosti: | ||
| Line 384: | Line 232: | ||
| OPERAND | OPERAND | ||
| OČEKIVANI REZULTAT | OČEKIVANI REZULTAT | ||
| - | |||
| Vrijednosti su u trojkama, prva vrijednost je operacija koja će se izvršiti, odnosno vrijednost 0-7 koja određuje koji switch case 0-7 će se izvršiti, druga vrijednost je operand, treća vrijednost je očekivani rezultat. Za svaki od 21 user input charactera, postoji odgovarajuća trojka. | Vrijednosti su u trojkama, prva vrijednost je operacija koja će se izvršiti, odnosno vrijednost 0-7 koja određuje koji switch case 0-7 će se izvršiti, druga vrijednost je operand, treća vrijednost je očekivani rezultat. Za svaki od 21 user input charactera, postoji odgovarajuća trojka. | ||
| + | Pregled prvih triju vrijednosti je prikazan na slici ispod. | ||
| - | Pregled prvih triju vrijednosti je prikazan na slici 22. | + | {{ rev2_ghidra: |
| - | + | ||
| - | Slika 22. - prvih tri vrijednosti | + | |
| - | local_158 | + | |
| - | + | ||
| - | {{ : | + | |
| - | + | ||
| - | Ovdje se može vidjeti da je prva vrijednost 2, što znači da će se izvršiti switch case 2, koji je ADD (+), operand je 0x92, a očekivani rezultat je 0xd5. | + | Ovdje se može vidjeti da je prva vrijednost 2, zbog koje će se izvršiti switch case 2, koji je ADD (+), operand je 0x92, a očekivani rezultat je 0xd5. |
| - | Što znači | + | Odnosno |
| < | < | ||
| Line 406: | Line 247: | ||
| </ | </ | ||
| - | odnosno | + | Iz ovoga se može zaključiti koji je očekivani znak korisničkog unosa |
| < | < | ||
| Line 414: | Line 255: | ||
| 0xd5 - 0x92 je 0x43, odnosno 67 u dekadskom zapisu, što odgovara ASCII vrijednosti " | 0xd5 - 0x92 je 0x43, odnosno 67 u dekadskom zapisu, što odgovara ASCII vrijednosti " | ||
| + | Sada se ili ovako " | ||
| - | + | U Python | |
| - | Sada se ili ovako " | + | |
| - | + | ||
| - | + | ||
| - | U python | + | |
| < | < | ||
| Line 425: | Line 263: | ||
| </ | </ | ||
| - | I nakon toga možemo samo prekopirati sve linije koje sadržavaju definirane vrijednosti varijable local_158, kao što su prikazane na slici 20. | + | I nakon toga možemo samo prekopirati sve linije koje sadržavaju definirane vrijednosti varijable local_158, kao što su prikazane na slici 21. |
| - | + | ||
| - | Ovime već imamo validan python kod, u kojem smo definirali sve spremljene operacije, operande i rezultate koji se trebaju izvršiti kao u programu. | + | |
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | Slika 23. - prijenos varijable local_158 u python | + | |
| - | + | ||
| - | {{ : | + | |
| - | + | ||
| + | Ovime već imamo validan Python kod, u kojem smo definirali sve spremljene operacije, operande i rezultate koji se trebaju izvršiti kao u programu. | ||
| + | {{ rev2_ghidra: | ||
| Dodavanjem ovog koda na kraj, možemo dobiti ispis operacija i očekivanih rezultata koji se izvršavaju u programu. | Dodavanjem ovog koda na kraj, možemo dobiti ispis operacija i očekivanih rezultata koji se izvršavaju u programu. | ||
| - | Slika 24. - simulacija programske logike rev2 zadatka | + | {{ rev2_ghidra: |
| - | {{ :slika24.png? | + | Pokretanjem koda sada dobivamo ispis svih operacija nad korisničkim unosom i očekivane rezultate tih operacija: |
| + | {{ rev2_ghidra: | ||
| - | Pokretanjem koda sada dobivamo ispis svih operacija nad korsiničkim unosom i očekivane rezultate tih operacija: | + | Sada se samo Python programski kod za ispis operacija programa |
| - | + | ||
| - | Slika 25. - programska logika rev2 zadatka | + | |
| - | + | ||
| - | {{ : | + | |
| - | + | ||
| - | + | ||
| - | Sada se samo Python programski kod sa slike 22 može promijeniti da radi inverz operacija za svih 7 slučaja, tako nađe korisnički input koji bi riješio | + | |
| - | + | ||
| - | Slika 26. - Inverz operacija zadatka | + | |
| - | + | ||
| - | {{ : | + | |
| + | < | ||
| + | local_158 = [0] * 63 | ||
| + | local_158[0x38] = 0xca | ||
| + | local_158[0x39] = 7 | ||
| + | local_158[0x3a] = 0 | ||
| + | local_158[0x3b] = 0xcc | ||
| + | local_158[0] = 2 | ||
| + | local_158[1] = 0x92 | ||
| + | local_158[2] = 0xd5 | ||
| + | local_158[3] = 7 | ||
| + | local_158[4] = 0 | ||
| + | local_158[5] = 0xac | ||
| + | local_158[6] = 7 | ||
| + | local_158[7] = 0 | ||
| + | local_158[8] = 0xba | ||
| + | local_158[9] = 7 | ||
| + | local_158[10] = 0 | ||
| + | local_158[0xb] = 0xce | ||
| + | local_158[0xc] = 1 | ||
| + | local_158[0xd] = 0x42 | ||
| + | local_158[0xe] = 0x72 | ||
| + | local_158[0xf] = 1 | ||
| + | local_158[0x30] = 1 | ||
| + | local_158[0x31] = 0xb3 | ||
| + | local_158[0x32] = 0x87 | ||
| + | local_158[0x33] = 4 | ||
| + | local_158[0x34] = 0x89 | ||
| + | local_158[0x35] = 0xf8 | ||
| + | local_158[0x36] = 6 | ||
| + | local_158[0x37] = 0 | ||
| + | local_158[0x10] = 0x7f | ||
| + | local_158[0x11] = 0x4d | ||
| + | local_158[0x12] = 7 | ||
| + | local_158[0x13] = 0 | ||
| + | local_158[0x14] = 0xcb | ||
| + | local_158[0x15] = 4 | ||
| + | local_158[0x16] = 0xf1 | ||
| + | local_158[0x17] = 0xab | ||
| + | local_158[0x18] = 6 | ||
| + | local_158[0x19] = 0 | ||
| + | local_158[0x1a] = 0xce | ||
| + | local_158[0x1b] = 4 | ||
| + | local_158[0x1c] = 0x6b | ||
| + | local_158[0x1d] = 0xbc | ||
| + | local_158[0x1e] = 1 | ||
| + | local_158[0x1f] = 0x7d | ||
| + | local_158[0x3c] = 2 | ||
| + | local_158[0x3d] = 0x98 | ||
| + | local_158[0x3e] = 0xf5 | ||
| + | local_158[0x20] = 0x44 | ||
| + | local_158[0x21] = 1 | ||
| + | local_158[0x22] = 0xe5 | ||
| + | local_158[0x23] = 0xd4 | ||
| + | local_158[0x24] = 7 | ||
| + | local_158[0x25] = 0 | ||
| + | local_158[0x26] = 200 | ||
| + | local_158[0x27] = 4 | ||
| + | local_158[0x28] = 0xdd | ||
| + | local_158[0x29] = 7 | ||
| + | local_158[0x2a] = 5 | ||
| + | local_158[0x2b] = 7 | ||
| + | local_158[0x2c] = 0x9a | ||
| + | local_158[0x2d] = 7 | ||
| + | local_158[0x2e] = 0 | ||
| + | local_158[0x2f] = 0xcc | ||
| - | Pokretanjem ovog programa, dobiva se rješenje zadatka | + | def reconstructUserInput(operation, operand, expected_result): |
| + | def ret(b): | ||
| + | return chr(b & 0xFF) | ||
| + | match operation: | ||
| + | case 1: # XOR | ||
| + | return ret(expected_result ^ operand) | ||
| + | case 2: # ADD | ||
| + | return ret((expected_result - operand) & 0xFF) | ||
| + | case 3: # SUB | ||
| + | return ret((expected_result + operand) & 0xFF) | ||
| + | case 4: # MUL | ||
| + | # solve (user * operand) & 0xFF == expected_result | ||
| + | # since all values are printable and operand is invertible modulo 256, use brute force | ||
| + | for x in range(256): | ||
| + | if (x * operand) & 0xFF == expected_result: | ||
| + | return ret(x) | ||
| + | case 5: # SHIFT (rotate-left) | ||
| + | n = operand & 7 | ||
| + | for x in range(256): | ||
| + | if ((x << n) | (x >> (8 - n))) & 0xFF == expected_result: | ||
| + | return ret(x) | ||
| + | case 6: # BITWISE NOT (no operand) | ||
| + | return ret((~expected_result) & 0xFF) | ||
| + | case 7: # ADD (no operand) | ||
| + | return ret((-expected_result) & 0xFF) | ||
| + | i = 0 | ||
| + | user_input_solve = "" | ||
| + | while i < 63: | ||
| + | operation = local_158[i] | ||
| + | operand = local_158[i + 1] | ||
| + | expected_result =local_158[i + 2] | ||
| - | Slika 27. - rješenje zadatka | + | userInput = reconstructUserInput(operation, |
| - | {{ : | + | print(userInput) |
| + | |||
| + | user_input_solve += userInput | ||
| + | i += 3 | ||
| + | print(" | ||
| + | </ | ||
| - | Napomena: | ||
| - | Preporučuje se da kad radite reversing, probate otvoriti datoteku i s drugim alatima za reverzno inženjerstvo, | + | Pokretanjem ovog programa |
| + | {{ rev2_ghidra: | ||
| - | Slika 28. - Binary Ninja prikaz rev2 | + | ==Napomena== |
| - | {{ : | + | Preporučuje se da kad radite reversing, probate otvoriti datoteku i drugim alatima za reverzno inženjerstvo, |
| + | {{ rev2_ghidra: | ||
| - | Može se vidjeti da je Binary Ninja odmah uspješno rekonstruirala | + | Može se vidjeti da je Binary Ninja odmah uspješno rekonstruirala |
rev2_ghidra.1761838122.txt.gz · Last modified: 2025/12/01 11:40 (external edit)