Sto usando ASM e vogliono riscrivere qualcosa di simile:Iniettando un metodo Java _prima_ un altro metodo è chiamato
someMethod().targetMethod(args...)
a:
someMethod().injectedMethod(arg).targetMethod(args...)
Il guaio è che io non so quale sia la metodo prima è, conosco solo il metodo di destinazione (quindi trovare someMethod()
e iniettare dopo che non è un'opzione).
Ho anche molte versioni del metodo di destinazione, con diversi set di parametri con cui desidero lavorare.
utilizzando ASM posso facilmente trovare il metodo di destinazione invocazione, ma purtroppo lo stack operando in quel punto è:
[ argN, ..., arg1, instance, ... ]
E mentre io riesco a capire quanto in basso l'istanza sarà, non c'è bytecode I può iniettare che lo leggerà. So che puoi farlo per un massimo di 4 parametri usando trucchi con comandi dup, ma ho bisogno di una soluzione generale.
Potrei aggiungere un po 'di variabili locali e copiare tutto dallo stack, duplicare l'istanza puntata e rimettere tutto su, ma questa è un'inefficienza di runtime che davvero non voglio.
Quello che penso potrebbe funzionare è se potessi tenere traccia delle istruzioni che sono state responsabili dell'inserimento del puntatore dell'istanza nello stack e quindi è stato possibile inserire la chiamata al metodo piuttosto che al richiamo del metodo di destinazione. Tuttavia non ho avuto fortuna nel trovare qualcosa che mi aiuti a farlo.
So che cose come AspectJ lo consentono, ma devono farlo per un sacco di classi mentre si caricano e AspectJ è troppo lento.
Qualcuno può indicarmi strumenti di analisi basati su ASM che potrebbero consentirmi di farlo o qualcuno potrebbe pensare ad un approccio migliore per l'iniezione di una chiamata di metodo prima di un'altra?
Non capisco, hai davvero bisogno di usare ASM? perché sembra che tu stia cercando di hackerare un Jar esistente. Per questo sarebbe meglio decompilarlo ......... Se no, e stai scrivendo un'applicazione java, non puoi usare l'aggregazione per quello? – fredcrs
Non riesco a decompilare le classi perché posso collegarlo solo come javaagent in fase di caricamento della classe. Non sto né "hackerando un jar esistente" o "scrivendo un'applicazione Java"; Sto iniettando bytecode in classi mentre vengono caricati. – David
Ho lavorato con [Soot] (http://www.sable.mcgill.ca/soot/) mentre ero a scuola e facevo cose esattamente come questa (OK forse un po 'meno complicato). Guarda. Sfortunatamente, non so se è costruito su ASM. L'unica altra opzione che viene in mente è AspectJ. – arin