että instrumentointi ei ole helposti mahdollista, koska JIT on laatinut IL-ohjeet.
No, se on itse asiassa päinvastoin. Jäljitysmenetelmät ovat melko helppoja - olisi vaikeaa, jos haluaisimme jäljittää kenttien käyttötarkoitukset. .NET-kokoonpanot sisältävät runsaasti tyyppiä / menetelmää koskevia tietoja, joita voidaan käyttää niiden tarkastamiseen / muokkaamiseen. Siellä on myös upea kirjasto, joka tekee sen ja paljon muuta - Mono.Cecil.
Tämän kirjaston avulla voimme saavuttaa haluamasi ( pääsisältö) ).
käyttäen System; käyttämällä System.IO; käyttäen System.Linq; käyttämällä Mono.Cecil; käyttämällä Mono.Cecil.Cil; class TraceIL {static void Main (string [] args) { if (args.Pituus! = 1) {Console.WriteLine ("TraceIL.exe <assembly>"); palata; } merkkijonon tiedostonimi = args [0]; ModuleDefinition module = ModuleDefinition.ReadModule (fileName); MethodReference consoleWriteLine = module.ImportReference (typeof (Console) .GetMethod ("WriteLine", uusi tyyppi [] {typeof (object)})); foreach (TypeDefinition type in module.Types) {foreach (var methodDefinition in type.Methods) {var ilBody = methodDefinition.Body; var ilProcessor = ilBody.GetILProcessor (); var firstOp = methodDefinition.Body.Instructions.First (); var ldstrEntering = Instruction.Create (OpCodes.Ldstr, $ "- syötetään {methodDefinition.Name}"); ilProcessor.InsertBefore (firstOp, ldstrEntering); var call = Instruction.Create (OpCodes.Call, consoleWriteLine); ilProcessor.InsertBefore (firstOp, kutsu); var ldstrLeaving = Instruction.Create (OpCodes.Ldstr, $ "- Leaving {methodDefinition.Name}"); var lastOp = methodDefinition.Body.Instructions.Last (); ilProcessor.InsertBefore (lastOp, ldstrLeaving); ilProcessor.InsertBefore (lastOp, puhelu); }}
module.Write (Path.GetFileNameWithoutExtension (fileName) + ". muokattu" + Path.GetExtension (fileName)); }}
Vain selittääkseen vähän mitä tapahtuu. Jokaisesta kokoonpanossa löydetystä tyypistä jokaiselle menetelmälle saadaan ILProcessor
, jonka avulla voimme muokata koodia. Tämän jälkeen lisäämme vain merkkijonon ja kutsun Console.WriteLine
-tilaan juuri ennen ensimmäistä olemassa olevaa opcode-koodia ja vastaavaa koodia juuri ennen menetelmän loppua. Lopussa tallennamme uuden binaarin samalla nimellä, johon on lisätty .modified
.
Esimerkki:
λ TestApp.exe
Inside Run
Inside Inside
MoreInside
OtherProgramRun
λ TraceIL.exe TestApp.exe
λ TestApp.modified. exe
- Pääsivun syöttäminen
- Sisäänsyöttö .ctor
- Lähtö .ctor
- Sisäänajo
Sisäajo
- Sisäänkäynti Inside Inside
--Entering MoreInside
MoreInside
--Ecting .ctor
--Leaving .ctor
--Entering OtherProgramRun
OtherProgramRun --Leaving OtherProgramRun
--Leaving MoreInside
--Leaving Inside
--Leaving Run
--Leaving Main
Tietysti siellä voit tehdä hulluja juttuja, kuten lisätä aikaleiman ja / tai luettelon hyväksytyistä argumenteista jne. Koska näytteesi on hämärtynyt, se ei ehkä toimi alusta, mutta luulen, että tätä koodia ei ole niin vaikea muutetaan muodossa tarvitaan.