Kysymys:
Mikä on "päällekkäisten ohjeiden" peittäminen?
perror
2013-04-03 13:11:29 UTC
view on stackexchange narkive permalink

Analysoin joitain binäärejä versiossa x86 / x86-64 käyttäen joitain hämärtymistemppuja. Yksi oli nimeltään päällekkäiset ohjeet . Voisiko joku selittää, miten tämä hämärtyminen toimii ja miten kiertää?

Olen miettinyt, mikä on oikea termi tälle. Olen kuullut, että 'käskyjakaumaa' käytetään melko usein.
Koen useita tapoja puhua tästä tekniikasta. Mutta on totta, että yhteisö ei hyväksynyt laajalti yhtään. "_Overlaping Instructions_" oli eniten käytetty, mitä löydän nyt. Mutta olen ehkä lukenut vain pienen osan olemassa olevista asiakirjoista.
Neljä vastused:
Remko
2013-04-03 13:25:43 UTC
view on stackexchange narkive permalink

Paperissa x86-suoritettavien tiedostojen staattinen analyysi selitetään päällekkäiset ohjeet melko hyvin. Seuraava esimerkki on otettu siitä (sivu 28):

  0000: B8 00 03 C1 BB mov eax, 0xBBC103000005: B9 00 00 00 05 mov ecx, 0x05000000000A: 03 C1 add eax, ecx000C : EB F4 jmp $ -10000E: 03 C3 add eax, ebx0010: C3 ret  

Koodia tarkastelemalla ei ole selvää, mikä arvo eax on palautuskäskyssä ( tai että palautusohje on koskaan saavutettu). Tämä johtuu siirtymästä 000C: stä 0002: een, osoitteeseen, jota ei nimenomaisesti ole luettelossa (jmp $ -10 tarkoittaa suhteellista hyppyä nykyisestä ohjelmalaskurin arvosta, joka on 0xC ja 0xC10 = 2). Tämä hyppy siirtää ohjauksen viiden tavun pitkän siirtymiskäskyn kolmannelle tavulle osoitteessa 0000. Tavujonon suorittaminen osoitteesta 0002 alkaen avaa täysin uuden käskyvirran:

  0000: B8 00 03 C1 BB mov eax, 0xBBC103000005: B9 00 00 00 05 mov ecx, 0x05000000000A: 03 C1 lisää eax, ecx000C: EB F4 jmp $ -100002: 03 C1 lisää eax, ecx0004: BB B9 00 00 00 mov ebx, 0xB90009: 05 03 C1 EB F4 add eax, 0xF4EBC103000E: 03 C3 add eax, ebx0010: C3 ret  

Olisi mielenkiintoista tietää, hoitavatko / miten Ida Pro ja etenkin Hex Rays -laajennus. Ehkä @IgorSkochinsky voi kommentoida tätä ...

Ange
2013-04-08 19:47:54 UTC
view on stackexchange narkive permalink

Se tunnetaan myös nimellä 'hypätä keskelle' temppu.

selitys

suoritussäännöt

  • useimmat ohjeet vievät useamman kuin yhden tavun koodattava
    • ne voivat viedä jopa 15 tavua nykyaikaisilla suorittimilla
  • suoritus voi alkaa missä tahansa paikassa, kunhan käyttöoikeudet ovat voimassa

joten mitä tahansa tavun ensimmäistä seuraavaa tavua voidaan käyttää uudelleen toisen käskyn aloittamiseen.

purkijoiden väärinkäyttö

  • suoraviivaiset purkajat aloittavat seuraava ohje heti viimeisen päättymisen jälkeen.

joten tällaiset purkajat (jotka eivät seuraa virtausta) piilottavat keskellä olevat ohjeet näkyvän yhden.

esimerkkejä

triviaali

  00: EB 01 jmp 302: 68 c3 90 90 90 push 0x909090c3  

suoritetaan tehokkaasti kuten

  00: EB 01 jmp 303: C3 retn ...  

kun ensimmäinen jmp ohittaa ensimmäisen tavun 68 (joka koodaa välitöntä työntöä) seuraavasta ohjeesta.

useita päällekkäisyyksiä

tästä esimerkistä, 69 84 määrittelee imul -käskyn, joka voi viedä jopa 11 tavua. Voit siis sovittaa useita käskyriviä sen väärennettyihin operandeihin.

  00: EB02 jmp 402: 69846A40682C104000EB02 imul eax, [edx + ebp * 2 + 0102C6840], 0x002EB00400D: ... .  

suoritetaan todella nimellä

  00: EB02 jmp 404: 6A40 push 04006: 682C104000 push 0x40102C0B: EB02 jmp 0xF0F: ...  

ohjeet menevät päällekkäin itsensä kanssa

Käsky hyppää itsensä toisessa tavussa:

  00: EBFF jmp 102: C0C300 rol bl, 0  

suoritetaan todella nimellä

  00: EBFF jmp 101: FFC0 inc eax03: C3 retn  

eri suorittimen tilat

tämä hämärtyminen voidaan laajentaa hyppäämään samaan EIP: hen, mutta eri suorittimen tilassa:

  • 64b-suorittimet tukevat edelleen 32b-ohjeita
  • 64b-tila käyttää 0x33 -toimintoa cs
  • jotkut ohjeet ovat saatavana vain tietyssä tilassa:
    • arpl 32b-tilassa
    • movsxd 64b-tilassa

joten voit siirtyä samaan EIP -kohtaan, mutta käyttämällä eri CS -toimintoa ja saada erilaisia ​​ohjeita.

Tässä esimerkissä tämä koodi suoritetaan ensin 32b-tilassa:

  00: 63D8 arpl ax, bx02: 48 dec eax03: 01C0 add eax, eax05: CB retf  

ja suoritetaan sitten uudelleen 64-bittisessä tilassa seuraavasti:

  00: 63D8 movsxd rbx, eax02: 4801C0 add rax, rax05: CB retf  

Tässä tapauksessa ohjeet ovat päällekkäisiä, ei toisen EIP: n takia, vaan siksi, että keskusyksikkö muuttui tilapäisesti tilasta 32b tilaan 64b.

Onko mahdollista vaihtaa 32-bittisestä 64-bittiseksi tilassa ohjelmana, joka toimii käyttäjän tilassa missä tahansa suurimmissa käyttöjärjestelmissä?
@Dougall kyllä. Windowsissa se tapahtuu `X86SwitchTo64BitMode ()` (tai manuaalisesti kaukopuhelulla / hyppyllä segmentinvalitsimella 33). Olen kuitenkin varma, että tämä on nimenomaan Windows WOW64 -käyttöönottoa eikä sovellettavissa toisessa käyttöjärjestelmässä.
@Ange, voitko päivittää linkin https://code.google.com/p/corkami/source/browse/trunk/src/CoST/CoST.asm?r=1593#2247? Kiitos!
joxeankoret
2013-04-03 14:19:39 UTC
view on stackexchange narkive permalink

Lähes mitä tahansa monitavuista käskyä voidaan käyttää päällekkäisinä käskyinä tiedostoissa x86 / x86_64. Syy on erittäin helppo: x86- ja x86_64-komentojoukot ovat CISC. Mikä tarkoittaa muun muassa, että ohjeilla ei ole kiinteää pituutta. Joten koska käsky on vaihtelevan pituinen, kirjoittamalla konekoodi huolellisesti, jokainen käsky voi piilottaa päällekkäiset ohjeet.

Esimerkiksi, kun annetaan seuraava koodi:

  [ 0x00408210: 0x00a31e10] > b0x000050f5 (01) 56 PUSH ESI 0x000050f6 (04) 8b742408 MOV ESI, [ESP + 0x8] 0x000050fa (01) 57 PUSH EDI 0x000050fb (03) cxe003 (03) c1e3 ESI + 0x40a058] 0x00005104 (01) 57 PUSH EDI 0x00005105 (06) ff15f4804000 CALL 0x004080f4; 1 KERNEL32.dll! GetModuleHandleA0x0000510b (02) 85c0 TESTI EAX, EAX 0x0000510d (02) 750b JNZ 0x0000511a; 2 

Oletetaan, että jossain viimeisen käskyn jälkeen on hyppy näytetyn koodin jonkin käskyn keskelle, esimerkiksi MOV ESI: n 2. tavuun ... ohje:

  [0x000050f7: 0x00405cf7] > c0x000050f7 (02) 7424 JZ 0x0000511d; 1 0x000050f7 ------------------------------------------------ ---------------------- 0x000050f9 (03) 0857c1 TAI [EDI-0x3f], DL 0x000050fc (02) e603 OUT 0x3, AL  

Osoittautuu, että tämä ohje muuttuu JZ: ksi. Mikä on kelvollinen. Siirtyminen 3. tavuun ...

  [0x000050f7: 0x00405cf7] > s +1 [0x000050f8: 0x00405cf8] > c0x000050f8 (02) 2408 JA AL, 0x8 0x00000050 (01) (03) c1e603 SHL ESI, 0x3 0x000050fe (06) 8bbe58a04000 MOV EDI, [ESI + 0x40a058]  

Siirtyminen CALL-käskyn toiseen tavuun:

  [0x000050f5: 0x00405cf5] > s 0x5106 [0x00005106: 0x00405d06] > c0x00005106 (05) 15f4804, 05x15x4080; '\ x8e \ x91'0x0000510b (02) 85c0 TESTI EAX, EAX 0x0000510d (02) 750b JNZ 0x0000511a; 1 

Kuten näette, käytännössä mitä tahansa monitavuista käskyä voidaan käyttää päällekkäisenä käskynä.

Tätä peruutuksenvastaista temppua käytetään melko usein läpinäkymättömät predikaatit vuokaavion f ** k saamiseksi.

Joten tarkoitat, että tällaista luetteloa ei ole mahdollista rakentaa? Toinen asia, joka yllättää minut paljon x86 / x86-64-opkodeista, on sen kyky synkronoitua hetken kuluttua alkuperäiseen käskyvirtaan. Tämä ominaisuus auttaa myös paljon käskyjen päällekkäisyydessä. Minulla ei kuitenkaan ole aavistustakaan, miksi uudelleensynkronointi toimii niin hienosti.
Dougall
2013-04-08 20:16:04 UTC
view on stackexchange narkive permalink

Koska x86-käskyt voivat olla minkä tahansa pituisia eikä niitä tarvitse tasata, yhden käskyn välitön arvo voi olla kokonaan toinen käsky. Esimerkiksi:

  00000000 0531C0EB01 add eax, 0x1ebc03100000005 055090EB01 add eax, 0x1eb90500000000A 05B010EB01 add eax, 0x1eb10b00000000F EBF0 jmp short 0x1  

, kunnes hyppy. Kun se hyppää, välittömästä lisäyksestä eax: lle tulee käsky, joten koodi näyttää tältä:

  00000000 05 db 500000001 31C0 xor ax, ax xor ax, ax00000003 EB01 jmp short 0x600000005 05 db 500000006 50 työntöakselin työntöakseli00000007 90 nop00000008 EB01 jmp lyhyt 0xb0000000A 05 db 50000000B B010 mov al, 0x10 mov al, 0x10 ....  

Oikealla näkyvät tosiasiallisesti merkittävät ohjeet -käsi sarake. Tässä esimerkissä lyhyitä hyppyohjeita ohitetaan käskyn add eax -osa ( 05 ). On huomattava, että tämä voitaisiin tehdä tehokkaammin käyttämällä yksitavuisia syötteitä 05 s, kuten 3C05 , joka on cmp al, 0x5 , ja se olisi vaaraton koodissa, joka ei välitä lipuista.

Yllä olevassa kuviossa voit helposti korvata kaikki 05 -merkit 90 <: lla. code> (nop) nähdäksesi oikean purkamisen. Tämä voidaan tehdä hankalammaksi käyttämällä 05 s -arvoja piilotetun koodin välittöminä arvoina (josta suoritus riippuu). Todellisuudessa koodia hämärtävä henkilö ei todennäköisesti käytä add eax -tunnistetta uudestaan ​​ja uudestaan ​​ja saattaa muuttaa suoritusjärjestystä, jotta se olisi jäljitettävämpi.

Valmistin näytteen käyttämällä yllä olevaa mallia. Tämä on 32-bittinen Linux ELF-tiedosto base64: ssä. Piilokoodin vaikutus on käynnissä execve ("// usr / bin / python", 0, 0) . Ehdotan, ettet suorita satunnaisia ​​binäärejä SE-vastauksista. Voit kuitenkin käyttää sitä testaaaksesi purkajat. IDA, Hopper ja objdump kaikki epäonnistumme ensi silmäyksellä, vaikka kuvittelen saat HVT tehdä se oikein jotenkin.

  f0VMRgEBAQAAAAAAAAAAAAIAAwABAAAAYIAECDQAAAAoAQAAAAAAADQAIAABACgAAwACAAEAAAAAAAAAAIAECACABAgUAQAAFAEAAAUAAAAAEAAAAAAAAAAAAAAAAAAABTHA6wEFUJDrAQWwEOsBBffg6wEF9 + DrAQWJw + sBBbRu6wEFsG / rAQX34 + sBBbRo6wEFsHTrAQVQkOsBBbR56wEFsHDrAQX34 + sBBbQv6wEFsG7rAQVQkOsBBbRp6wEFsGLrAQX34 + sBBbQv6wEFsHLrAQVQkOsBBbRz6wEFsHXrAQX34 + sBBbQv6wEFsC / rAQVQkOsBBTHJ6wEF9 + HrAQWJ4 + sBBbAL6wEFzYDrAelN //// AC5zaHN0cnRhYgAudGV4dAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAEAAAAGAAAAYIAECGAAAAC0AAAAAAAAAAAAAAAQAAAAAAAAAAEAAAADAAAAAAAAAAAAAAAUAQAAEQAAAAAAAAAAAAAAAQAAAAAAAAA =  


Tämä Q & A käännettiin automaattisesti englanniksi.Alkuperäinen sisältö on saatavilla stackexchange-palvelussa, jota kiitämme cc by-sa 3.0-lisenssistä, jolla sitä jaetaan.
Loading...