PDA

View Full Version : [C] Elf loader cercasi


Teo@Unix
14-06-2010, 23:29
Mi chiedo da una buona mezz'ora se è possibile caricare un elf in memoria...

cioè vorrei caricarmi l'eseguibile in memoria un pò come si fà su windows con l'accoppiata LoadLibrary() e GetProcAddress() ed avere il mio indirizzo di partenza.

So che per caricare le librerie condivise si utilizza dlopen(), questa naturalmente mi da picche se tento di passargli un eseguibile come argomento.... oppure stò sbagliando qualcosa?

Sapete consigliarmi? Grazie.

eraser
15-06-2010, 00:30
Intendi qualcosa tipo mmap() (http://www.opengroup.org/onlinepubs/000095399/functions/mmap.html)?

Teo@Unix
15-06-2010, 13:52
Grazie per la risp.

Si, poi ieri sera ho pensato anche a mmap().

La mia perplessità è che non ho trovato da nessuna parte una indicazione che dice "...a si, si fa con mmap()".

Programmi come readelf altrimenti come fanno?
Più tardi vado a vedermi il sorgente magari...

con mmap se non mi sbaglio ottengo l'indirizzo di partenza che mi serve ok?

Ad esempio su NT so che per leggere nel PE devo fare:

...
hFile = CreateFile("prova.exe", GENERIC_READ, FILE_SHARE_READ, 0,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

if (hFile == INVALID_HANDLE_VALUE)
{
printf("Cannot Open the File\n");
return -1;
}

hMapObj = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, 0);

if (!hMapObj)
{
...
}

if (!(hBaseAddress = MapViewOfFile(hMapObj, FILE_MAP_READ, 0, 0, 0)))
{
...

eraser
15-06-2010, 14:24
Sì, su Windows è corretto, nel senso che con CreateFileMapping/MapViewOfFile puoi già mappare in memoria l'eseguibile rilocato

(Se comunque vuoi andare ad analizzare il PE header del file non c'è bisogno di mapparlo in memoria, puoi fare una conversione RVA/raw per muoverti all'interno del file senza doverlo mappare)

Su Linux sinceramente non lo so, non sono esperto di questo sistema operativo :) Ho provato a spolverare qualche remota conoscenza :)

Teo@Unix
15-06-2010, 15:01
Sì, su Windows è corretto, nel senso che con CreateFileMapping/MapViewOfFile puoi già mappare in memoria l'eseguibile rilocato

(Se comunque vuoi andare ad analizzare il PE header del file non c'è bisogno di mapparlo in memoria, puoi fare una conversione RVA/raw per muoverti all'interno del file senza doverlo mappare)


già infatti meglio così:

...
hFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, 0,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

if (hFile == INVALID_HANDLE_VALUE)
{
...
}
FileSize = GetFileSize(hFile, NULL);

BaseAddress = (BYTE *) malloc(FileSize);

if (!ReadFile(hFile, BaseAddress, FileSize, &BR, NULL))
{
....
}
...

Su linux mo vedo di trovare il modo leggendo i sorgenti di readelf...
ma io credo che per forza si usa mmap()... questa mi restituirà l'indirizzo di partenza come GetProcAddress()... Faccio alcune prove... :)

Intanto grazie.

marco.r
15-06-2010, 16:22
Mi chiedo da una buona mezz'ora se è possibile caricare un elf in memoria...

cioè vorrei caricarmi l'eseguibile in memoria un pò come si fà su windows con l'accoppiata LoadLibrary() e GetProcAddress() ed avere il mio indirizzo di partenza.

So che per caricare le librerie condivise si utilizza dlopen(), questa naturalmente mi da picche se tento di passargli un eseguibile come argomento.... oppure stò sbagliando qualcosa?

Sapete consigliarmi? Grazie.
Cosa ci devi fare con questo eseguibile ? Eseguirlo o altro ?

Teo@Unix
15-06-2010, 16:35
Cosa ci devi fare con questo eseguibile ? Eseguirlo o altro ?

No, non lo devo eseguire altrimenti mi basterebbe utilizzare execve().

Devo solo accedere alla struttura del file, header sezioni ecc ecc...

pabloski
15-06-2010, 16:39
è libelf la libreria che fa al caso tuo

eraser
15-06-2010, 16:39
No, non lo devo eseguire altrimenti mi basterebbe utilizzare execve().

Devo solo accedere alla struttura del file, header sezioni ecc ecc...

Allora basta tranquillamente un fread del C e poi ci lavori con le strutture classiche importando libelf.h :)

Teo@Unix
15-06-2010, 16:50
Allora basta tranquillamente un fread del C e poi ci lavori con le strutture classiche importando libelf.h :)

ma io credo sia diverso da come è su disco...
correggimi se sbaglio, ma su windows so che molte cose vengono piazzate dal loader nell'immagine di processo... (senza contare le librerie).

dite che è uguale leggendo direttamente?

eraser
15-06-2010, 17:08
ma io credo sia diverso da come è su disco...
correggimi se sbaglio, ma su windows so che molte cose vengono piazzate dal loader nell'immagine di processo... (senza contare le librerie).

dite che è uguale leggendo direttamente?

Se fai un'analisi del solo file eseguibile, in Windows sostanzialmente se lo analizzi da come è su disco o come è caricato in memoria cambia poco, l'unica grande rogna è che se è caricato già in memoria e rilocato puoi muoverti all'interno di esso in maniera più agevole perché gli indirizzi espressi nel PE header sono già relativi (RVA). Invece se lo leggi da disco devi convertire gli indirizzi RVA in indirizzi fisici sul file per poterti muovere in maniera adeguata tra le varie sezioni dell'header PE

Teo@Unix
15-06-2010, 21:59
L'utility readelf usa fread().

Deduco che usare mmap() non sia necessario per il mio obiettivo...
lo scoprirò vivendo.

Grazie per i vostri consigli. :)