2016-06-23 26 views
6

Sto svolgendo alcune attività di reverse engineering verso i binari sull'architettura 32-bit x86.Ottimizzazione dell'allocazione di memoria: da heap a stack

Recentemente ho trovato alcune interessanti ottimizzazioni dal codice sorgente C al programma di assemblaggio.

Ad esempio, il codice sorgente originale è come (questo codice sorgente è da openssl library):

powerbufFree = (unsigned char *)malloc(powerbufLen); 

E dopo la compilazione (gcc version 4.8.4 -O3), il codice assembly è come questo:

807eaa0: cmp eax, 0xbff       # eax holds the length of the buf. 
807eaa5: mov dword ptr [ebp-0x68], eax   # store the length of powerbuf on the stack 
807eaa8: jnle 0x807ec60       # 0x807ec60 refers to the malloc 
807eaae: mov edx, eax 
807eab0: add eax, 0x5e 
807eab3: and eax, 0xfffffff0 
807eab6: sub esp, eax 
807eab8: lea eax, ptr [esp+0x23] 
807eabc: and eax, 0xffffffc0 
807eabf: add eax, 0x40 
807ead3: mov dword ptr [ebp-0x60], eax # store the base addr of the buf on the stack. 

Con mia sorpresa, il buf è effettivamente assegnato in pila !!! Sembra una ottimizzazione per l'allocatore di heap per me, ma non ne sono sicuro.

Quindi ecco la mia domanda, l'ottimizzazione di cui sopra (malloc -> stack allocation) sembra familiare a qualcuno? Ha senso? Qualcuno potrebbe fornire qualche manuale/specifica su tale ottimizzazione?

+0

dov'è la chiamata di malloc? \ –

+1

Ciò mi ricorda molto l'analisi di fuga in JVM più recenti. https://en.wikipedia.org/wiki/Escape_analysis Se la memoria non vivrà mai al di fuori della chiamata di funzione, potrebbe essere allocata in modo sicuro dallo stack. Se hai lo spazio nel tuo stack, questa sarà una allocazione/coppia di operazioni molto più veloce. – Sam

+0

Penso che l'heap sia una struttura ad albero generale. Attraversando l'heap con il metodo di ricerca del metodo Depth, gli elementi visitati in sequenza dall'ordine di uno stack. –

risposta

5

Dal source of bn_exp.c:

0634 #ifdef alloca 
0635  if (powerbufLen < 3072) 
0636   powerbufFree = alloca(powerbufLen+MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH); 
0637  else 
0638 #endif 
0639  if ((powerbufFree=(unsigned char*)OPENSSL_malloc(powerbufLen+MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL) 
0640   goto err; 

noti che 0xbff è uguale a 3071. Nei sistemi che lo supportano, alloca fa stack di allocazione. Questo è vero per GNU version, che viene utilizzato da Linux e BSD implementations copiato questa API da 32V UNIX da AT & T (according to FreeBSD).

Si guardava solo la riga 639. Ma se è stato definito alloca, il codice C corrisponde al proprio assieme.

Spesso l'ottimizzazione viene utilizzata per evitare le spese di utilizzo di malloc per un buffer temporaneo se l'allocazione è relativamente piccola. Per C.1999, invece, è possibile utilizzare un VLA (dal C.2011, VLA è una funzionalità opzionale).

A volte, l'ottimizzazione utilizza solo un buffer di dimensioni fisse di dimensioni ragionevolmente piccole. Ad esempio:

char tmp_buf[1024]; 
char *tmp = tmp_buf; 

if (bytes_needed > 1024) { 
    tmp = malloc(bytes_needed); 
} 
/* ... */ 
if (tmp != tmp_buf) { 
    free(tmp); 
} 
+0

Grazie per il vostro aiuto ... Sono così incurante in questo momento ... – computereasy

Problemi correlati