Vorrei analizzare. Assiemi .Net indipendenti da C#, VB.NET o altro.
Conosco Roslyn e NRefactory ma sembrano funzionare solo sul livello del codice sorgente C#?
C'è anche il progetto "Common Compiler Infrastructure: Code Model and AST API" su CodePlex che dichiara di "supportare un modello di oggetto gerarchico che rappresenta blocchi di codice in una forma strutturata indipendente dalla lingua" che suona esattamente per quello che sto cercando.
Tuttavia, non sono in grado di trovare alcuna documentazione o codice utile che sia effettivamente in esecuzione.
Qualche consiglio su come archiviare questo?
Posso forse fare qualcosa Mono.Cecil?Ottieni AST da. Assemblaggio Net senza codice sorgente (codice IL)
risposta
Per quanto ne so, non è possibile costruire AST da binario (senza origini) poiché AST stesso generato dal parser come parte del processo di compilazione da fonti. Mono.Cecil non aiuta perché è possibile modificare solo opcode/metadati con essi, non analizzare l'assembly.
Ma dal momento che è .NET è possibile scaricare il codice IL da dll con l'aiuto di ildasm. Quindi è possibile passare sorgenti generate a qualsiasi parser con il dizionario CIL collegato e ottenere AST dal parser. Il problema è che per quanto ne so c'è solo una grammatica CIL pubblicamente disponibile per il parser, quindi non hai una scelta. E ECMA-355 è abbastanza grande quindi è una cattiva idea scrivere la tua grammatica. Così ti posso suggerire solo una soluzione: il montaggio
- Pass Ildasm.exe per ottenere CIL.
- Poi passare CIL per ANTLR v3 parser con this CIL grammatica cablato (si noti che è un po 'datato - grammatica creato il 2004 e più recenti specifiche CIL è il 2006, ma CIL in realtà non cambia di molto)
- Dopo di che si possono accedere gratuitamente AST generato da ANTLR
Nota che sarà necessario ANTLR non v3 v4, dal momento che la grammatica scritta per il 3 ° versione, ed è quasi impossibile portarlo a v4 senza una buona conoscenza della sintassi ANTLR.
Inoltre si può provare a guardare in nuove Microsoft ryujit fonti del compilatore a github (parte di CoreCLR) - Non sicuro che sia aiuta, ma in teoria il mosto contengono CIL grammatica e parser implementazioni poiché funziona con Codice CIL. Ma è scritto in CPP, ha un'enorme base di codice e manca di documentazione poiché è in fase di sviluppo attivo, quindi potrebbe essere più facile rimanere bloccato con ANTLR.
Se si considera il file binario .net come un flusso di byte, si dovrebbe essere in grado di "analizzare" correttamente.
Basta scrivere una grammatica i cui token sono essenzialmente byte. Puoi certamente costruire un lexer/parser classico con quasi tutti gli strumenti di lexer/parser definendo il lexer per leggere singoli byte come token.
È quindi possibile creare l'AST utilizzando i macchinari di costruzione standard AST per il motore di analisi (da soli per YACC, automaticamente con ANTLR4).
Quello che scoprirete, ovviamente, è che "analizzare" non è abbastanza; dovrai ancora costruire tabelle di simboli ed eseguire analisi di controllo e flusso di dati se stai per fare un'analisi seria del codice corrispondente. Vedi il mio saggio su LifeAfterParsing.
È anche probabile che si debbano prendere in considerazione funzioni "distinte" che forniscono funzionalità di runtime chiave ai linguaggi di programmazione specifici che hanno effettivamente generato il codice CIL. E questi renderanno i tuoi analizzatori dipendenti dalla lingua. Sì, puoi ancora condividere la parte dell'analisi che funziona con CIL generico.
Il formato di file binario .NET non si qualifica come privo di contesto (o sensibile al contesto), quindi né YACC né ANTLR saranno in grado di generare un parser per questo. –
Dove violano c-free o c-sensitive? –
1) La posizione di varie strutture all'interno del modulo è specificata con un RVA (indirizzo virtuale relativo), la ricerca dell'offset all'interno del file richiede la mappatura tramite la tabella delle sezioni. 2) I conteggi delle righe per ogni tabella vengono visualizzati prima di ognuno di essi, questi conteggi possono influire su determinate larghezze delle colonne. 3) La maggior parte delle DLL che ho esaminato collocano i metadati dopo i corpi delle funzioni (sebbene ciò non sia richiesto) quindi se stai leggendo solo in un modo forward (come con un parser generato), non saprai quando hai incontrato un metodo body fino a molto tempo dopo averlo passato. –
È possibile eseguire questa operazione ed è disponibile anche una (anche se piccola) example of this nell'origine di ILSpy.
var assembly = AssemblyDefinition.ReadAssembly("path/to/assembly.dll");
var astBuilder = new AstBuilder(new DecompilerContext(assembly.MainModule));
decompiler.AddAssembly(assembly);
astBuilder.SyntaxTree...
Il CCI Model Code è da qualche parte tra un disassemblatore IL e pieno C# decompilatore: dà il codice di qualche struttura (ad esempio if
dichiarazioni ed espressioni), ma contiene anche alcune operazioni in bassa pila livello come push
e pop
.
CCI contiene un esempio che mostra questo: PeToText.
Ad esempio, per ottenere il codice del modello per il primo metodo del tipo Program
(nel namespace globale), è possibile utilizzare il codice come questo:
string fileName = "whatever.exe";
using (var host = new PeReader.DefaultHost())
{
var module = (IModule)host.LoadUnitFrom(fileName);
var type = (ITypeDefinition)module.UnitNamespaceRoot.Members
.Single(m => m.Name.Value == "Program");
var method = (IMethodDefinition)type.Members.First();
var methodBody = new SourceMethodBody(method.Body, host, null, null);
}
Per dimostrare, se si decompilare quanto sopra codice e vederlo con PeToText, si sta andando ad ottenere:
Microsoft.Cci.ITypeDefinition local_3;
Microsoft.Cci.ILToCodeModel.SourceMethodBody local_5;
string local_0 = "C:\\code\\tmp\\nuget tmp 2015\\bin\\Debug\\nuget tmp 2015.exe";
Microsoft.Cci.PeReader.DefaultHost local_1 = new Microsoft.Cci.PeReader.DefaultHost();
try
{
push (Microsoft.Cci.IModule)local_1.LoadUnitFrom(local_0).UnitNamespaceRoot.Members;
push Program.<>c.<>9__0_0;
if (dup == default(System.Func<Microsoft.Cci.INamespaceMember, bool>))
{
pop;
push Program.<>c.<>9.<Main0>b__0_0;
Program.<>c.<>9__0_0 = dup;
}
local_3 = (Microsoft.Cci.ITypeDefinition)System.Linq.Enumerable.Single<Microsoft.Cci.INamespaceMember>(pop, pop);
local_5 = new Microsoft.Cci.ILToCodeModel.SourceMethodBody((Microsoft.Cci.IMethodDefinition)System.Linq.Enumerable.First<Microsoft.Cci.ITypeDefinitionMember>(local_3.Members).Body, local_1, (Microsoft.Cci.ISourceLocationProvider)null, (Microsoft.Cci.ILocalScopeProvider)null, 0);
}
finally
{
if (local_1 != default(Microsoft.Cci.PeReader.DefaultHost))
{
local_1.Dispose();
}
}
di nota sono tutte quelle dichiarazioni push
, pop
e dup
e la condizione di caching lambda.
- 1. Ottenere il codice sorgente di clang AST
- 2. Come passare al codice sorgente MVC4 senza assemblaggio di costruzione
- 3. Come generare AST dal codice sorgente Java?
- 4. Visualizza il codice sorgente da un "Symbols Server" senza debugging?
- 5. Come posso confrontare due file di codice sorgente/ast alberi?
- 6. Download di codice sorgente .NET 4
- 7. Ottieni codice sorgente HTML dal browser CefSharp
- 8. Ottieni codice sorgente HTML come stringa
- 9. php: Ottieni il codice sorgente html con cURL
- 10. Navigazione nel codice sorgente di .NET Framework da Visual Studio
- 11. Il miglior design per generare codice da un AST?
- 12. Traduci codice C# in AST?
- 13. Eventuali strumenti per la generazione di codice JavaScript da AST
- 14. Estratto Attributi da C# codice sorgente senza Riflessione
- 15. package NuGet con codice sorgente senza SymbolSource.org
- 16. Golang: proteggere il codice sorgente
- 17. distribuzione django binario (senza codice sorgente)
- 18. Ottieni il codice di uscita da subshell attraverso le pipe
- 19. Debugging del codice sorgente di NET Framework non disponibile
- 20. parsing del codice sorgente C++ nell'ambiente java
- 21. Come utilizzare. Assemblaggio Net da Win32 senza registrazione?
- 22. Codice sorgente haskell pretty-print con commenti
- 23. SyntaxHighlighter codice sorgente v3.0.83
- 24. Codice Java: ricerca del codice sorgente
- 25. Installazione del codice sorgente di riferimento .NET (RSCC)
- 26. Profiler Golang non trova il codice sorgente
- 27. Codice byte al codice sorgente Java
- 28. Esegui codice .NET 3.0 da Office 2003
- 29. Debug JBoss codice sorgente
- 30. Come analizzare il codice sorgente di Blender
Se si desidera solo ottenere l'IL, questo approccio è troppo convoluto. Usare Cecil sarà molto più semplice. – svick