2011-09-11 14 views
5

Dopo aver rebasato il programma principale molto in alto nella propria imagebase.C++ Come controllare Image Base dell'API LoadLibrary

Come posso garantire che la DLL che viene caricato verrà caricato in 0x400000

dllImageBase = LoadLibrary("test.dll"); 
printf("imagebase = 0x%x", dllImageBase); 

Ho sempre trovato 0x460000 invece di 0x400000

Ho bisogno del mio dll prima istruzione di partire da 0x401000, ha usato per inizio alle 0x600000 prima rebasing

comando per linker rebase è

#pragma comment(linker, "/BASE:8000000") 

Quindi 0x400000 è in realtà gratuito in questo momento, ma non lo usa per impostazione predefinita .. quindi in qualsiasi modo posso controllarlo, dove dovrebbe trasferirsi. Forse WIN32API?

+0

Come sapete che "0x400000" è gratuito? Qualche altra DLL potrebbe essere lì. –

+0

Ho guardato la mappa della memoria e l'intestazione .code/PE del mio programma parte da '0x8000000' .. e prima che sia' 0x3300000' che è solo sortbls.nls e continua a essere sempre più in basso niente sta usando '0x4000000'. Ma cosa stai dicendo da qualche parte in futuro, si romperà per qualche strano incidente? questo è se capisco come impostare troppo 0x4000000. Poi di nuovo, se in qualche modo capisco come controllare questo, non li ricaricheranno mai più – SSpoke

+0

Non sono a conoscenza di alcun modo per controllarlo. Se il tuo codice dipende da una particolare DLL che vive in un particolare indirizzo, è rotto. Semplice come quello (ad esempio, x64 Windows tenta in particolare di randomizzare gli indirizzi in cui vengono caricate varie DLL come misura di sicurezza). –

risposta

5

È necessario disabilitare la Randomizzazione dello spazio degli indirizzi per caricare la DLL dove lo si desidera. Una funzionalità progettata per impedirti di ciò che stai cercando di fare./Opzione di collegamento DYNAMICBASE. Caricamento a 0x400000 ha funzionato quando ho provato.

+0

avviso lol LNK4044: opzione non riconosciuta "DYNAMICBASE: NO"; ignorato, suppongo che il mio compilatore non sia aggiornato – SSpoke

2

Non fare mai affidamento su una DLL che si carica in una base specifica. Se si potrebbe forzare il caricamento di DLL a una base specifica, si aprirà un potenziale buco di sicurezza.

Se si dispone di un file di mappa, si conosce l'offset di una determinata funzione. Pertanto è possibile utilizzare GetProcAddress per calcolare l'indirizzo di base della DLL. Questo è un modo molto più sicuro di funzionare anche se ciò significa che l'aggiornamento della DLL interrompe il caricamento del codice della DLL.

+0

Il codice assembly utilizza la matematica per generare il successivo offset di chiamata che è codificato in quello specifico indirizzo di base. So che è un po 'strano vederlo, ma in primo luogo non si è mai dovuto chiamare come funzione dll – SSpoke

+0

@SSpoke: Beh, se non riesci a calcolare l'indirizzo di base usando un trucco come suggerisco sopra, allora hai nessuna scelta se non quella di utilizzare la soluzione di Hans Passant. Tieni a mente che nulla garantisce che una versione successiva di Windows non romperà il tuo codice. Una soluzione diversa è sicuramente la miglior soluzione. Non sono affatto sicuro di cosa stia esattamente cercando di fare, tuttavia, mi sembra che tu possa usare qualsiasi indirizzo di base che scegli. – Goz

+0

Anche io desidero Goz, ma sto decodificando un enorme programma con 128 funzioni, la soluzione migliore sarebbe quella di convertire tutto quel assembly in codice C o almeno in linea, ma voglio una via di uscita pigra per ora, quindi ho convertito il exe a una DLL rimossa è main() e sostituito con un dllmain in modo che possa caricare con successo come dll ora – SSpoke