Pitanje:
Koji me nagovještaji u strojnom kodu mogu uputiti na kompajler koji je korišten za njegovo generiranje?
WilliamKF
2013-03-20 01:01:49 UTC
view on stackexchange narkive permalink

Kad gledam strojni kod aplikacije, postoje li savjeti i obrasci koje mogu razabrati iz generiranog strojnog koda koji bi naznačili koji je kompajler (i eventualno verzija) korišten za njegovo generiranje?

Pomaže li mi poznavanje kompajlera koji se koristi za generiranje aplikacije, da učinkovitije vratim inženjerstvo natrag s generiranog objekta na ono što je izvorni kôd mogao biti, i ako pomaže, kako to?

Kad kažete "pomozite mi da učinkovitije preusmjerim inženjering natrag s generiranog objekta na ono što je mogao biti izvorni kôd", je li vaš cilj dekompilirati kôd ili razumjeti funkcionalnost koda?
Je li uopće moguće potpuno dekompilirati kod? Rekao bih da se dekompilira ako je moguće, inače, da bih barem razumio funkcionalnost.
Sedam odgovori:
#1
+29
Andrew
2013-03-20 01:46:22 UTC
view on stackexchange narkive permalink

U ovom području postoje neka akademska istraživanja, ključne riječi koje želite su "poreklo lanca alata". O ovoj je temi bio prilično dobar članak Natea Rosenbluma, prošlo je neko vrijeme otkako sam pročitao ovaj članak, ali možete upotrijebiti mnoge tehnike za utvrđivanje ovih podataka. Mislim da neki koriste strojno učenje, a drugi mogu koristiti veliku hrpu heuristike ili aksioma o ponašanju sastavljača.

Utvrđivanje je ovog ograničenog korisnog IMO-a. Moglo bi biti korisno u kontradiktornoj situaciji u kojoj pokušavate dobiti podatke o grupi zlonamjernih programa ili akteru prijetnje, ali imajte na umu da se ovakve informacije mogu prikriti ili uništiti. Jedna od potencijalnih upotreba ovih podataka bila bi utvrđivanje da je neki binarni softver sastavljen pomoću SDK-a nekih tvrtki koji je sadržavao kompajler s podacima o potpisu jedinstvenim za tu tvrtku. Utvrđivanjem porijekla lanca alata može vam pomoći da utvrdite da netko tko je kupio vaš SDK krši licencu ili ugovor, recimo proizvodnjom zlonamjernog softvera.

Primjer razlika u ponašanju je pisanje parametara. Postoje dva načina za postavljanje vrijednosti u stog, jedan pomoću 'push', a drugi pomoću mov s adresom koja se temelji na esp kao odredišnom operandu. Dakle, jedan kompajler može to učiniti:

 push eaxpush ebx 

A drugi to može učiniti:

 mov [esp + foo], eaxmov [esp + foo + 4], ebx 

I rade. Općenito, MSVC radi prvi, a GCC drugi primjer, barem u nekim vrlo ograničenim ispitivanjima / promatranjima upravo sada ...

#2
+10
Mike
2013-03-20 01:46:15 UTC
view on stackexchange narkive permalink

Kada se gleda Strojni kôd, obično postoji "trag" koji se može slijediti, osim ako proizvedeni binarni program nije nekako pročišćen. Na primjer, generirao sam malu aplikaciju "hello world" koristeći GCC na svom Linuxu s standardnim opcijama gcc -Wall hello.c sada ako uzmete alat poput hexedit kod> možete vidjeti u strojnom kodu postoji odjeljak koji sadrži informacije o gradnji:

enter image description here

Jasno je da tamo možete vidjeti da, izgradio sam ovo sa GCC verzija 4.6.3. Ostali kompajleri imat će druge vrste potpisa Microsoftov "bogati" potpis.

Zanimljivo je kako bi to izgledalo nakon uklanjanja datoteke ...
Pitanje se konkretno odnosilo na strojni kod. Mogli bismo se nadati da je OP već isprobao takve osnovne metode kao što je korištenje hex uređivača ili `objdump` i traženje trivijalnih nizova, prije nego što pita. U tom slučaju ovo ne bi bio odgovor. Ali sigurno, da nekako nisu, bilo bi relevantno. ;-)
@underscore_d - `" Nadao bi se ", zaista bi se. Jednostavno sam se pobrinuo da se ne moramo samo nadati da je OP to znao. Volim ne pretpostavljati previše pretpostavki!
#3
+9
Igor Skochinsky
2013-03-20 02:29:37 UTC
view on stackexchange narkive permalink

U Reconu je bila prezentacija pod nazivom "Packer Genetics: The Selfish Code" koja je opisala jedan pristup tome. Koristili su neke statistike za izdvajanje najčešćih sekvenci koda iz prevedenih programa i koristili ih za otkrivanje kraja raspakiranja, ali pristup se lako može koristiti za identificiranje određenih kompajlera.

Pogledajte sa slajda 15 ovdje: http://blog.zynamics.com/2010/07/16/recon-slides-packer-genetics-the-selfish-code-bochspython/

Slajdovi izgledaju donekle krnji , Vjerujem da je stvarna prezentacija imala više informacija.

#4
+7
Remko
2013-03-20 19:53:24 UTC
view on stackexchange narkive permalink

Pomaže li mi poznavanje kompajlera koji se koristi za generiranje aplikacije, da učinkovitije vratim inženjer natrag s generiranog objekta na ono što je izvorni kod mogao biti, i ako pomaže, kako onda?

Smatram upotrijebljeni kompajler vrlo važnim korakom iz sljedećih razloga:

  1. Pomaže vam u odabiru odgovarajućih alata za analizu cilja.
  2. Poznavanje vremena izvođenja važno je za analizu, na primjer u Delphiju TFileStream je često korišten objekt za čitanje / pisanje datoteka. Poznavanje vtable tog objekta pomaže mi da shvatim čita li se / piše / traži traženi pomak itd.

Da pojasnim 1 na primjeru: alat kao što je IDR možda bolje odgovara Delphi metu od IDA Pro-a. Ili barem pomoću nje možemo generirati MAP datoteku / IDC skriptu koja poboljšava simbole u IDA-i. Ali za cilj napisan u Visual Basicu može se koristiti VB Decompiler i tako dalje.

#5
+7
waliedassar
2013-04-17 11:57:13 UTC
view on stackexchange narkive permalink

Pretpostavljam da je prva stvar koju biste trebali učiniti da odredite verziju kompajlera, osim ako doslovno mislite na verziju kompajlera umjesto na verziju povezivača, pregledati polja "MajorLinkerVersion" i "MinorLinkerVersion" PE zaglavlja izvršne datoteke, bilo EXE , DLL ili SYS. Pogledajte popis u nastavku.

Major Minor

0x5 0x0 (5.0) Borland C ++ / MS Linker 5.0

0x6 0x0 (6.0) Microsoft VIsual Studio 6

0x7 0xA (7.10) Microsoft VIsual Studio 2003

0x8 0x0 (8.0) Microsoft VIsual Studio 2005

0x9 0x0 (9.0) Microsoft VIsual Studio 2008

0xA 0x0 (10.0) Microsoft VIsual Studio 2010

0x2 0x15 (2.21) MinGw

0x2 0x19 (2.0.0.25) Borland Delphi (povezivač 2.0.0.25)

Nažalost, pakeri i zaštitnici imaju tendenciju da prepišu ove vrijednosti da bi napisali svoje i / ili ojačali postupak pogađanja izvornog prevoditelja.

Također, direktorij resursa izvršne datoteke dobro je mjesto za pretraživanje određenih podataka o povezivaču. npr. RT_RCDATA koji ima resurs pod nazivom "DVCLAL" znak je Borland C ++ ili Delphi, a "RT_MANIFEST" u slučaju izvršne datoteke izgrađene od MSVC-a može nam reći o specifičnoj verziji runtime DLL-a na koji je povezan, a time i verziji kompajlera.

Također, izvršna datoteka s poljem "TimeDateStamp" postavljenim na 0x2A425E19 znak je izrade s Delphiem.

Sada, ako želite odrediti kompajler iz koda sklopa, tada znak nedavne verzije MSVC kompajlera vidi funkciju koja generira kolačić steka neposredno na ulaznoj točki.

Čini se da je JMP uputa na ulaznoj točki praćena nizom "fb: C ++ Hook" znak Borlanda C ++ i tako dalje.

#6
+4
Michael Anderson
2013-03-20 03:35:49 UTC
view on stackexchange narkive permalink

Pomaže li mi poznavanje kompajlera koji se koristi za generiranje aplikacije, da učinkovitije vratim inženjer natrag s generiranog objekta na ono što je izvorni kod mogao biti, i ako pomaže, kako onda?

Da, trebalo bi pomoći.

Još bolje:

  • točna verzija kompajlera;
  • točni parametri naredbenog retka;
  • okruženje gradnje (OS, razina zakrpe, ...).

Ideja je:

  • izgraditi test slučajeve za puno različitih slučajeva (mali mali programi) koji prikazuju različite strukture i sastavljaju ih;

  • pogledajte rezultirajući strojni kôd (primjećujući obrasce).

Mnogi od ovih slučajeva mogli bi se generalizirati na glavnu verziju kompajlera ( if i druge kontrolne strukture, osnovne jezične funkcije, ...).

Moguće je da postoje neke optimizacije specifične za kompajler koje se puno razlikuju za isti program.

(Pitam se postoje li knjižnice testnih slučajeva za comm on / korisni slučajevi za pomoć u obrnutom inženjerstvu strojnog koda koji generira određeni kompajler.)

Oprostite na otvorenosti, ali morate poraditi na oblikovanju i riješiti se slučajnih velikih slova. Trenutno je odgovor prilično teško pročitati.
Je li uređivanje bilo poboljšanje?
#7
+3
Yifan
2013-03-20 01:17:21 UTC
view on stackexchange narkive permalink

Ako samo govorite o strojnom kodu (ili kodu sklopa), nema puno podataka. Većina modernih kompajlera proizvest će sličan izlaz ili izlaz neće biti dovoljan da bi se vidjele razlike. Jedna stvar koja može nagovijestiti je optimizacija kompajlera, s kojom nisam iskusan, a netko drugi bi trebao nagovoriti. Ako imate cijelu ELF datoteku i ako su dostupni simboli, možda ćete moći donijeti zaključke na temelju vrsta knjižnice su povezane (na primjer, libgcc bi bila dijeljenje) ili imena funkcija specifičnih za kompajler. Ako ELF sadrži informacije o otklanjanju pogrešaka, možda ćete čak vidjeti i stvari poput "GCC: (Ubuntu / Linaro 4.6.3-1ubuntu5) 4.6.3". Ako imate posla s C ++ kodom, naziv simbola može ga dati.

Međutim, kao što ste se zapitali, znatiželjan sam zašto su vam potrebne ove informacije. Ne znam koliko ćete pomoći dobiti znajući da će to učiniti prevodilac. Više radim s ARM-om i znam da uz tu platformu postoji aplikacijsko binarno sučelje kojeg se moraju pridržavati kompajleri / kôd sklopa. Ovaj ABI daje informacije o tome kako se trebaju pozivati ​​funkcije, koje registre za što koristiti i itd. Znam za platforme bez strogog ABI-a, operativni sustavi programerima često daju informacije o takvim temama. Bez obzira na to, svi kompajleri trebali bi stvoriti kompatibilni kôd, tako da ne znam od kakve koristi za identificiranje kompajlera koji je stvorio kôd.

Ovom odgovoru nedostaje obrazloženje ili referenca zašto ne bi došlo do razlika u rezultatima. Moje osobno iskustvo s x86 proturječi tome, ali veličina uzorka je premala da bih mogao reći da je to istina općenito. Također pitanje zašto su potrebne ove informacije zapravo nije dio odgovora, već više zahtjev za pojašnjenjem i bolje bi se uklopio u komentar na pitanje.
Hvala na konstruktivnoj kritici. Nov sam u odgovorima na pitanja pa ne razumijem sve detalje. Pokušat ću pronaći još referenci.
Iznenađujući je broj razlika između prevoditelja, posebno u x86 kodu gdje postoji toliko različitih uputa za odabir. Promjene implementacija izraza, odluke o rasporedu stoga i odabir registara mogu pružiti natuknice koji je kompajler korišten.


Ova pitanja su automatski prevedena s engleskog jezika.Izvorni sadržaj dostupan je na stackexchange-u, što zahvaljujemo na cc by-sa 3.0 licenci pod kojom se distribuira.
Loading...