Quello che stai chiedendo è fattibile, ma non molto facile.
Un modo per farlo è compensare lo spostamento del codice nelle sue istruzioni. È necessario trovare tutte le istruzioni che utilizzano l'indirizzamento relativo al RIP (hanno il byte ModRM
di 05h, 0dh, 15h, 1dh, 25h, 2dh, 35h o 3dh) e regolano il loro campo disp32
in base alla quantità di spostamento (la mossa è quindi limitato a +/- 2 GB nello spazio degli indirizzi virtuali, che potrebbe non essere garantito dato che lo spazio degli indirizzi a 64 bit è maggiore di 4 GB).
È possibile anche sostituire quelle istruzioni con i loro equivalenti, molto probabilmente sostituendo ogni istruzione originale con più di uno, per esempio:
; These replace the original instruction and occupy exactly as many bytes as the original instruction:
JMP Equivalent1
NOP
NOP
Equivalent1End:
; This is the code equivalent to the original instruction:
Equivalent1:
Equivalent subinstruction 1
Equivalent subinstruction 2
...
JMP Equivalent1End
Entrambi i metodi richiedono almeno alcune routine x86 smontaggio rudimentali.
Il primo può richiedere l'uso di VirtualAlloc()
su Windows (o qualche equivalente su Linux) per garantire che la memoria che contiene la copia patchata del codice originale sia compresa tra +/- 2 GB di quel codice originale. E l'allocazione a indirizzi specifici può ancora fallire.
Quest'ultimo richiederà più di un semplice smontaggio primitivo, ma anche una decodifica e generazione di istruzioni complete.
Potrebbero esserci altre stranezze da aggirare.
confini istruzioni possono anche essere trovati impostando il flag TF
nel registro RFLAGS
per rendere la CPU genera l'interrupt single-step
di debug al termine dell'esecuzione di ogni istruzione. Un gestore di eccezioni di debug dovrà catturarle e registrare il valore di RIP dell'istruzione successiva. Credo che questo possa essere fatto usando Structured Exception Handling (SEH)
in Windows (mai provato con le interruzioni di debug), non sono sicuro di Linux. Affinché questo funzioni, dovrai eseguire tutto il codice, ogni istruzione.
Btw, c'è l'indirizzamento assoluto in modalità 64 bit, vedere, ad esempio, le istruzioni MOV da/accumulatore con opcode da 0A0h a 0A3h.
, il metodo -mcmodel = large dovrebbe essere la soluzione. devo indagare sul perché il compilatore gcc osx non lo supporta – nux
Forse è troppo vecchio. I modelli piccoli (standard) e di codice medio sono stati aggiunti presto, il modello più grande è venuto dopo. – hirschhornsalz
ti ringrazio tanto questo sembra molto buono e risolve definitivamente il problema di indirizzamento assoluto – nux