Compileren zonder libc

Ik wil mijn C-code compileren zonder de (g)libc. Hoe kan ik het deactiveren en welke functies zijn ervan afhankelijk?

Ik heb -nostdlib geprobeerd, maar het helpt niet: de code kan worden gecompileerd en wordt uitgevoerd, maar ik kan de naam van de libc nog steeds vinden in de hexdump van mijn uitvoerbare bestand.


Antwoord 1, autoriteit 100%

Als je je code compileert met -nostdlib, kun je (natuurlijk) geen C-bibliotheekfuncties aanroepen, maar je krijgt ook niet de gewone C-bootstrap-code. In het bijzonder is het echte startpunt van een programma op Linux niet main(), maar eerder een functie genaamd _start(). De standaardbibliotheken bieden normaal gesproken een versie hiervan die een initialisatiecode uitvoert en vervolgens main()aanroept.

Probeer dit te compileren met gcc -nostdlib -m32:

void _start() {
    /* main body of program: call main(), etc */
    /* exit system call */
    asm("movl $1,%eax;"
        "xorl %ebx,%ebx;"
        "int  $0x80"
    );
}

De functie _start()moet altijd eindigen met een aanroep om exit(of een andere niet-terugkerende systeemaanroep zoals exec). Het bovenstaande voorbeeld roept de systeemaanroep rechtstreeks aan met inline-assembly, aangezien de gebruikelijke exit()niet beschikbaar is.


Antwoord 2, autoriteit 11%

De eenvoudigste manier om de C-code te compileren om bestanden te object (gcc -com enkele *.o-bestanden te krijgen) en deze vervolgens rechtstreeks te koppelen met de linker ( ld). Je zult je objectbestanden moeten koppelen met een paar extra objectbestanden zoals /usr/lib/crt1.oom een ​​werkend uitvoerbaar bestand te krijgen (tussen het ingangspunt, zoals gezien door de kernel, en de functie main(), is er wat werk aan de winkel). Om te weten waar je mee moet linken, probeer te linken met de glibc, met behulp van gcc -v: dit zou je moeten laten zien wat er normaal in het uitvoerbare bestand komt.

Je zult zien dat gcc code genereert die afhankelijk kan zijn van een paar verborgen functies. De meeste staan ​​in libgcc.a. Er kunnen ook verborgen aanroepen zijn naar memcpy(), memmove(), memset()en memcmp(), die in de libc staan, dus het kan zijn dat je je eigen versies moet aanleveren (wat niet moeilijk is, tenminste zolang je niet te kieskeurig bent wat betreft prestaties).

Dingen kunnensoms duidelijker worden als je naar de geproduceerde assembly kijkt (gebruik de vlag -S).

Other episodes