Signatur nachträglich einfügen

  • VB.NET

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von lurker.

    Signatur nachträglich einfügen

    Hallo Leute!

    Ich habe schon vor längerer Zeit eine Lernsoftware geschrieben. Diese Software besteht ausschließlich aus der .exe-Datei (War der Ausdrückliche wunsch des Verages). Jetzt, nach gut einem halben Jahr, ist der Verleger nocheinmal zu mir gekommen mit dem Wunsch, dass dieser vor der Weitergabe den Namen der Schule in das Programm einbinden können sollte. Doch, wie auch hier möchte dieser NICHT eine 2. Datei mitliefern müssen, wo diese Daten gespeichert werden und auch nicht mit Visual Studios arbeiten müssen um die .exe-Datei ändern zu können. Ihm wäre ein einfaches Programm (von mir) zum ändern der eigentlichen Software am Liebsten. Und hier bin ich schon bei meiner Frage:
    Wie kann ich Nachträglich Daten in die .exe Datei bekommen/ändern? Es handelt sich um einen Einfachen String, welcher den Schulnamen beinhaltet.

    Würde mich über Denanstöße freuen!
    Mit freundlichen Grüßen



    GVI (Teil1/2): 80%

    tolio schrieb:


    Danke für deine Antwort. Ich kann es leider derzeit nicht probieren, doch dieses Tut sieht sehr vielversprechend aus. Wenn ich noch Fragen habe, werde ich mich hier nochmal melden. (Daumen bekommst du nachdem es funktioniert ;))

    /EDIT: Danke für diesen Link! Dieser hat ungemein weitergeholfen. Außerdem ist dieses Mono.CeCil eine extrem gute Libary.
    Mit freundlichen Grüßen



    GVI (Teil1/2): 80%

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „lurker“ ()

    Hallo Leute,

    ich habe wieder genau das Problem, was ich vor 3 Jahre gehabt habe. (Deshalb hab ich auch hier diesen Thread wieder herausgekrammt, falls dies nicht in Ordnung ist erstell ich gerne einen neuen.)
    Ich habe keinerlei Sicherung über dieses alte Projekt und muss nun diesen kleinen Part der Signatur nocheinmal schreiben. Leider ist der Link von tolio nicht mehr aktuell, obwohl dieser mir dazumals sehr weitergeholfen hat. Mit Googlen und dem Stichwort Mono.Cecil hab ich nun folgenden Code zusammengstell:

    C#-Quellcode

    1. ModuleDefinition module = ModuleDefinition.ReadModule(assemblyPath); //Pfad zur EXE
    2. MethodDefinition md = module.Types.First(t => t.FullName.Equals("MeinProjekt.Form1")).Methods.First(m => m.Name.Equals("getTitle")); //in der Klasse "Form1" die Methode getTitle()
    3. ILProcessor ilp = md.Body.GetILProcessor();
    4. ilp.InsertAfter(md.Body.Instructions.First(), Instruction.Create(OpCodes.Ldstr, "Irgend ein String"));

    Ich benutze das Mono.Cecil NuGet-Packet.

    Dieser sollte folgende Methoden ändern um den Titel des Programmes beim Starten umzugestallten.

    C#-Quellcode

    1. private void Form1_Load(object sender, EventArgs e)
    2. {
    3. Text = getTitle();
    4. }
    5. public string getTitle()
    6. {
    7. string title = " tes";
    8. return title;
    9. }


    Es wird kein Fehler in dem modifizierenden Projekt geworfen (Die Methode wird richtig gefunden). Der Titel in der Titelleiste ist jedoch nachwievor der gleiche.
    Muss ich vielleicht noch die Assembly irgendwie speicher? Wenn jemand irgend einen Rat hat freue ich mich ihn zu hören!
    Mit freundlichen Grüßen



    GVI (Teil1/2): 80%

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „lurker“ ()

    Danke für die schnelle Antwort!

    slice schrieb:

    AssemblyDefinition.Write(fileName)

    Ich hab damit eine neue Exe erstellt, soweit auch ganz gut. Doch leider ändert sich mit diesem Algorithmus, denn ich im oberen Post beschrieben habe nicht der Titel. Daher vermute ich, dass in diesem Code-Stückerl noch ein Fehler besteht. Folgendes habe ich derzeit:
    Spoiler anzeigen

    C#-Quellcode

    1. private void changeSavedFile()
    2. {
    3. string assemblyPath = tBxSaveTo.Text;
    4. ModuleDefinition module = ModuleDefinition.ReadModule(assemblyPath); //Pfad zur EXE
    5. MethodDefinition md = module.Types.First(t => t.FullName.Equals("MeinProjekt.Form1")).Methods.First(m => m.Name.Equals("getTitle")); //in der Klasse "Form1" die Methode getTitle()
    6. ILProcessor ilp = md.Body.GetILProcessor();
    7. ilp.InsertAfter(md.Body.Instructions.First(), Instruction.Create(OpCodes.Ldstr, "Irgend ein String"));
    8. module.Assembly.Write("C:/Users/Patrick/Desktop/neu.exe");
    9. }


    Hat jemand eine Idee, ob ich mit diesem Code überhaupt die injection richtig mache?

    PS: im "Hauptprogramm" sind diese 2 Methoden interessant:
    Spoiler anzeigen

    C#-Quellcode

    1. private void Form1_Load(object sender, EventArgs e)
    2. {
    3. Text = getTitle();
    4. }
    5. public string getTitle()
    6. {
    7. string title = " tes";
    8. return title;
    9. }

    Mit freundlichen Grüßen



    GVI (Teil1/2): 80%
    Hallo,

    ich habe es nun lösen können!
    Mithilfe dieser wunderbaren Seite (dotnetfiddle.net/) kann man sich den IL-Code von Algorithmen anzeigen lassen. In meinem Fall:
    Spoiler anzeigen

    C#-Quellcode

    1. // Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.33440
    2. // Copyright (c) Microsoft Corporation. All rights reserved.
    3. //
    4. // Metadata version: v4.0.30319
    5. .assembly extern mscorlib
    6. {
    7. .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
    8. .ver 4:0:0:0
    9. }
    10. .assembly xiogyuna
    11. {
    12. .hash algorithm 0x00008004
    13. .ver 0:0:0:0
    14. }
    15. .module xiogyuna.dll
    16. // MVID: {9B271877-2F8C-4B53-A7EA-7D5336E2CA6F}
    17. .imagebase 0x10000000
    18. .file alignment 0x00000200
    19. .stackreserve 0x00100000
    20. .subsystem 0x0003 // WINDOWS_CUI
    21. .corflags 0x00000001 // ILONLY
    22. // Image base: 0x01870000
    23. // =============== CLASS MEMBERS DECLARATION ===================
    24. .class public auto ansi beforefieldinit Program
    25. extends [mscorlib]System.Object
    26. {
    27. .method public hidebysig static void Main() cil managed
    28. {
    29. //
    30. .maxstack 8
    31. IL_0000: nop
    32. IL_0001: ldstr "Hello World"
    33. IL_0006: call void [mscorlib]System.Console::WriteLine(string)
    34. IL_000b: nop
    35. IL_000c: call string Program::getTitle()
    36. IL_0011: call void [mscorlib]System.Console::WriteLine(string)
    37. IL_0016: nop
    38. IL_0017: ret
    39. } // end of method Program::Main
    40. .method public hidebysig static string
    41. getTitle() cil managed
    42. {
    43. //
    44. .maxstack 1
    45. .locals init (string V_0,
    46. string V_1)
    47. IL_0000: nop
    48. IL_0001: ldstr " tes"
    49. IL_0006: stloc.0
    50. IL_0007: ldloc.0
    51. IL_0008: stloc.1
    52. IL_0009: br.s IL_000b
    53. IL_000b: ldloc.1
    54. IL_000c: ret
    55. } // end of method Program::getTitle
    56. .method public hidebysig specialname rtspecialname
    57. instance void .ctor() cil managed
    58. {
    59. //
    60. .maxstack 8
    61. IL_0000: ldarg.0
    62. IL_0001: call instance void [mscorlib]System.Object::.ctor()
    63. IL_0006: ret
    64. } // end of method Program::.ctor
    65. } // end of class Program
    66. // =============================================================
    67. //
    68. //


    Wobei jedoch ausschließlich der Teil für die getTitle()-Methode wichtig ist. Hier sieht man, dass sich entgegen meiner Annahme, dass sich die Anweisung den String zu laden an erster Stelle befindet, sich die Anweisung an zweiter Stelle befindet.

    Desweiteren habe ich den Code noch optimiert, dass dieser nicht 2x die "Ldstr" Anweisung aufruft und den Wert einfach überschreibt, sondern die Anweisung ersetzt wird. Hier nochmal der vollständige Code:
    Spoiler anzeigen

    C#-Quellcode

    1. ModuleDefinition module = ModuleDefinition.ReadModule("Pfad zu Datei");
    2. MethodDefinition md = module.Types.First(t => t.FullName.Equals("MeinProjekt.Form1")).Methods.First(m => m.Name.Equals("getTitle")); //in der Klasse "Form1" die Methode getTitle()
    3. ILProcessor ilp = md.Body.GetILProcessor();
    4. if (tBxName.Text.Length != 0)
    5. {
    6. ilp.Replace(md.Body.Instructions.First(x => x.OpCode == OpCodes.Ldstr), Instruction.Create(OpCodes.Ldstr, " - " + tBxName.Text));
    7. }
    8. module.Assembly.Write(tBxSaveTo.Text);


    Danke an alle die sich hierüber Gedanken gemacht haben.
    Mit freundlichen Grüßen



    GVI (Teil1/2): 80%