Announcement

Collapse
No announcement yet.

ReiPatcher - General Purpose .Net Assembly Patcher

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • [Utilities] ReiPatcher - General Purpose .Net Assembly Patcher

    ReiPatcher is a General Purpose .Net Assembly Patcher powered by Mono.Cecil
    Fully configurable by ini files, allowing for multiple Game Configurations, for example

    Requires .Net Framework 3.5

    Download: 0.9.0.8
    Password: byreisen
    ChangeLog:
    • 0.9.0.4 - Fixed a few Bugs, and updated some public method signatures
    • 0.9.0.5 - Changed "Skipping Patch" Color, since people were interpreting it as an error
    • 0.9.0.6 - Internal Stuff (AnyCPU Targeting)
    • 0.9.0.7 - Fixed bug when trying to instance an abstract class
    • 0.9.0.8 - Fixed bug when resolving assemblies


    File Structure should be similar to this:
    Code:
    ReiPatcher.exe
    <Configuration.ini>
    Mono.Cecil.dll
    Mono.Cecil.Mdb.dll
    Mono.Cecil.Pdb.dll
    Mono.Cecil.Rocks.dll
    ExIni.dll
    Patches\CM3D2.TranslationPlugin.Patcher.dll
    Patches\CM3D2.TexLoader.Patcher.dll
    Patches\<Other Patch DLLs>
    Creating a Patcher: (For Mod Developers - Refer to the AS-Wiki page for more information)
    • Download the Development Version
    • Add a Reference from 'ReiPatcher.exe' and 'Mono.Cecil'
    • Inherit 'PatchBase'
    • Override the Methods
    • Add your Patch to the Patchers directory


    Using the Patcher:
    • Create a Configuration File by running 'ReiPatcher -fc <Name>'
    • Edit the Configuration File with the instructions provided inside it
    • Place the Patchers DLLs into the specified Patches Folder
    • Execute the Patcher via 'ReiPatcher -c <Name>'


    Attached below are CM3D2 + UnityInjector Ready Configuration Files
    EDIT: Added AppLocale Versions

    Either create a shortcut targeting 'ReiPatcher.exe -c <configFile>' (CM3D2x64, CM3D2x86, CM3D2x64_AL or CM3D2x86_AL) or call it directly via command prompt/batch
    <configFile> is a placeholder, don't put the file name between <>!
    You may force repatching from the backups (to uninstall patches) by calling 'ReiPatcher.exe -c <configFile> -r' instead
    Don't forget to remove the Patcher DLLs if you want to uninstall them with the above method!
    Attached Files
    Last edited by usagirei; 10-13-2015, 08:52 AM. Reason: Updated Configs to 1.0.4.0
    Signature Space Critical, You can find most of my links and stuff Here now.
    CM3D2: Loaders | Translation | Signboard | Body-Writing
    SBPR: Loaders

    CM3D2 HF Patch (v120.0)
    CM3D2.ToolKit - Pre Release

  • #2
    Reserving some space
    Signature Space Critical, You can find most of my links and stuff Here now.
    CM3D2: Loaders | Translation | Signboard | Body-Writing
    SBPR: Loaders

    CM3D2 HF Patch (v120.0)
    CM3D2.ToolKit - Pre Release

    Comment


    • #3
      Thanks for this amazing tool!

      I have a question.
      I'm trying to make a mod that removes the fading from the interface to speed it up.

      Can I somehow change a parameter that is passed to the method I want to change and use that to execute it?

      Code:
      public void FadeOut(float f_fTime = 0.5f, bool f_bUIEnable = false, global::CameraMain.dgOnCompleteFade f_dg = null, bool f_bSkipable = true)
      I think all that would be necessary might be to make sure the f_fTime is 0.0f and every FadeOut should be instant, but when I redirect the method, change the variable and then execute normally (by returning false) it doesn't seem to take effect.
      Any way to do this?


      For now I managed to remove FadeOut by redirecting the entire method to a version that just always tries to complete the fade instantly no matter what duration was passed, but it's not very elegant and I can't make it work when I add FadeIn in the same way, at least not yet.

      For reference, this is what it looks like right now:
      Code:
              public static bool Skip_FadeOut(CameraMain cam, float f_fTime = 0.5f, bool f_bUIEnable = false, global::CameraMain.dgOnCompleteFade f_dg = null, bool f_bSkipable = true)
              {
                  if (f_dg != null) cam.m_dgOnCompleteFadeOut = (global::CameraMain.dgOnCompleteFade)Delegate.Combine(cam.m_dgOnCompleteFadeOut, f_dg);
                  cam.CompleteFadeOut();
                  return true;
              }
      Also I tried to make CameraMain m_eFadeState public by using ReiPatcherPlus but I can't seem to make it work.
      m_eFadeState is a CameraMain.FadeState enum which were both protected. I changed m_eFadeState to public and it shows up but Visual Studio complains that it's inaccessible due to it's protection level.
      So I tried making the FadeState enum base public but it's not working.



      Am I doing something wrong? Any advice? :-)

      Comment


      • #4
        Originally posted by shinizaya View Post
        -- snip --
        I am not usagirei, of course, but I am simply guessing what he would say: use IL to patch the method however you want, since clearly ReiPatcherPlus lacks in usability for now.

        That is true, but until the new version of ReiPatcherPlus is released (I am working hard on it to make it as flexible and simple as ever), you're either to write your own CLI code to patch the method, or fiddle with what you have.

        For instance, if you want to overwrite method parameters, you could try doing the following:
        Code:
        public static bool Skip_FadeOut(CameraMain cam, float f_fTime, bool f_bUIEnable, CameraMain.dgOnCompleteFade f_dg, bool f_bSkipable)
        {
            cam.FadeOut(0.0F, f_bUIEnable, f_dg, f_bSkipable); // pass whichever values you want, or use the stock values
            return true;  // if using ReiPatcherPlus, returning true will stop the original FadeOut call
        }
        As for turning those members fields into public: it works. Just make sure you refrence Assembly-CSharp directly from CM3D2 instead of copying it to another location (as opposed what is said in the wiki). That way, your IDE will see those fields as public after you apply the patch.

        However, as of ReiPatcherPlus 1.0.0.0, making nested classes (enums, classes, interfaces inside other classes) public is impossible. Simply because I forgot to implement that.

        In fact, I thank you for pointing such a silly bug out. I didn't bother to test the ChangeAccess simply because it was too simple a method. I guess one should test even small things.

        The fact that it does not function does not mean you can't do it yourself. After all, the method is quite simple.
        If you don't want to wait for the fix (which might come out either tomorrow -- or at least this week), use this ChangeAccess method that is the fixed version:
        Spoiler
        Code:
        public static void ChangeAccess(TypeDefinition type,
                                                string member,
                                                bool makePublic = true,
                                                bool makeVirtual = true)
                {
                    type.Methods.Where(m => m.Name == member).ForEach(
                    m =>
                    {
                        m.IsVirtual = makeVirtual;
                        m.IsPublic = makePublic;
                        m.IsPrivate = !makePublic;
                    });
        
                    type.Fields.Where(f => f.Name == member).ForEach(
                    f =>
                    {
                        f.IsPrivate = !makePublic;
                        f.IsPublic = makePublic;
                    });
                    type.NestedTypes.Where(f => f.Name == member).ForEach(
                    f =>
                    {
                        f.IsPublic = makePublic;
                    });
                }
        Last edited by denikson; 08-10-2015, 11:33 PM.

        Comment


        • #5
          Thanks a ton, I will try that.

          I must say I'm surprised about your example to change the parameters as I assumed if I call the redirected method it contains the code to call my method at the start and it would result in an endless loop.

          After trying it just now it doesn't seem to work, the Kiss logo never appears.

          Sooo.. just do it manually with IL, huh...just read that forum entry where you talked to usagirei where you two talk about using IL, it seems that's the way to accomplish what I'm trying to do here... I have not a clue about IL, that's a problem. lol
          All I know is C# pretty much...

          So I'm kinda reliant on ReiPatcherPlus. Not good enough to handle these things myself. I only got so far thanks to your tutorial on the wiki (thanks a lot for that!)

          Comment


          • #6
            Originally posted by shinizaya View Post
            Thanks a ton, I will try that.

            I must say I'm surprised about your example to change the parameters as I assumed if I call the redirected method it contains the code to call my method at the start and it would result in an endless loop.

            After trying it just now it doesn't seem to work, the Kiss logo never appears.

            Sooo.. just do it manually with IL, huh...just read that forum entry where you talked to usagirei where you two talk about using IL, it seems that's the way to accomplish what I'm trying to do here... I have not a clue about IL, that's a problem. lol
            All I know is C# pretty much...

            So I'm kinda reliant on ReiPatcherPlus. Not good enough to handle these things myself. I only got so far thanks to your tutorial on the wiki (thanks a lot for that!)
            That is true; so far the technique is far form perfect.
            Now that you mentioned the endless loop (which I, again, failed to notice), you could basically make a trigger boolean:

            Code:
            private static bool isOwnCall = false;
            
            public static bool Skip_FadeOut(CameraMain cam, float f_fTime, bool f_bUIEnable, CameraMain.dgOnCompleteFade f_dg, bool f_bSkipable)
            {
                if(isOwnCall) return false; // Do not trigger the hook if it is our own
                isOwnCall = true;
                cam.FadeOut(0.0F, f_bUIEnable, f_dg, f_bSkipable); // pass whichever values you want, or use the stock values
                isOwnCall = false; // We are done with our own call
                return true;  // if using ReiPatcherPlus, returning true will stop the original FadeOut call
            }
            That MAY work; again, I am just writing that from my head -- no testing whatsoever.

            But again, you either use what you have for now, wait for newer version of ReiPatcherPlus (which does allow to overwrite method parameters), or patch your own CLI code.
            I will work on a basic tutorial for injecting direct IL into methods in the near future (especially given that Mono.Cecil does not have any official and proper documentation).

            But hush for now, this is a thread for ReiPatcher, not ReiPatcherPlus. Let us keep the topics in their appropriate places.

            Comment


            • #7
              I'm getting an odd error when trying to patch the game....

              Code:
              Unhandled Exception: System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
                 at System.Reflection.Assembly.nLoadFile(String path, Evidence evidence)
                 at System.Reflection.Assembly.LoadFile(String path)
                 at ReiPatcher.Program.LoadPatchers(PatchBase[]& patchers) in W:\Projects\ReiPatcher\Source\Program.ExitCode.cs:line 102
                 at ReiPatcher.Program.CallAndKill(Func`1 function, Func`2 predicate) in W:\Projects\ReiPatcher\Source\Program.ExitCode.cs:line 43
                 at ReiPatcher.Program.Main_Internal(String[] args) in W:\Projects\ReiPatcher\Source\Program.cs:line 115
                 at ReiPatcher.Program.Main(String[] args) in W:\Projects\ReiPatcher\Source\Program.cs:line 97
              Any ideas? I've tried running the patcher as administrator, but it doesn't work when I do that...
              Last edited by Katzbalger; 08-17-2015, 02:57 AM.

              Comment


              • #8
                Originally posted by Katzbalger View Post
                I'm getting an odd error when trying to patch the game....

                Code:
                Unhandled Exception: System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
                   at System.Reflection.Assembly.nLoadFile(String path, Evidence evidence)
                   at System.Reflection.Assembly.LoadFile(String path)
                   at ReiPatcher.Program.LoadPatchers(PatchBase[]& patchers) in W:\Projects\ReiPatcher\Source\Program.ExitCode.cs:line 102
                   at ReiPatcher.Program.CallAndKill(Func`1 function, Func`2 predicate) in W:\Projects\ReiPatcher\Source\Program.ExitCode.cs:line 43
                   at ReiPatcher.Program.Main_Internal(String[] args) in W:\Projects\ReiPatcher\Source\Program.cs:line 115
                   at ReiPatcher.Program.Main(String[] args) in W:\Projects\ReiPatcher\Source\Program.cs:line 97
                Any ideas? I've tried running the patcher as administrator, but it doesn't work when I do that...
                The game is not in the program files dir by any chances is it?
                If it its, you won't be able to patch it while it's there i'm afraid (windows security reasons)
                Signature Space Critical, You can find most of my links and stuff Here now.
                CM3D2: Loaders | Translation | Signboard | Body-Writing
                SBPR: Loaders

                CM3D2 HF Patch (v120.0)
                CM3D2.ToolKit - Pre Release

                Comment


                • #9
                  Originally posted by usagirei View Post
                  The game is not in the program files dir by any chances is it?
                  If it its, you won't be able to patch it while it's there i'm afraid (windows security reasons)
                  The game is installed into D:\KISS\CM3D2

                  Comment


                  • #10
                    Any idea why I am getting this msg when I run CM3D2x64.exe? (after doing the reipatch)


                    必用アーカイブがありません。GameData\csv.arc

                    and the game screen starts all black and freezes..
                    Last edited by pushto; 08-18-2015, 06:16 AM.

                    Comment


                    • #11
                      Originally posted by pushto View Post
                      Any idea why I am getting this msg when I run CM3D2x64.exe? (after doing the reipatch)


                      必用アーカイブがありません。GameData\csv.arc

                      and the game screen starts all black and freezes..
                      You're probably using deflarc and haven't extracted the arcs
                      OR
                      You're not using deflarc and the .arcs aren't present, but are extracted instead
                      Signature Space Critical, You can find most of my links and stuff Here now.
                      CM3D2: Loaders | Translation | Signboard | Body-Writing
                      SBPR: Loaders

                      CM3D2 HF Patch (v120.0)
                      CM3D2.ToolKit - Pre Release

                      Comment


                      • #12
                        Took me a bit to figure this out, but Bitdefender reports UnityInjector.patches.dll to be a trojan. The HF patch and manually copying both gave me an access denied because the file continued to go into quarantine. I'll be scanning the file on several other antiviruses but I highly doubt it actually is malware. If anyone has issues with this file, disable your antivirus and add the file to exclusions.

                        Comment


                        • #13
                          I hate to bump issues, but I'm still stumped and can't get ReiPatcher to work. Any ideas on what I should try to remedy my issue? I also don't have an antivirus program running.

                          *EDIT* Actually I've just noticed ReiPatcher and the injector don't even work when I start the game anymore...
                          Last edited by Katzbalger; 08-21-2015, 01:55 AM.

                          Comment


                          • #14
                            Where is the game install located?
                            Signature Space Critical, You can find most of my links and stuff Here now.
                            CM3D2: Loaders | Translation | Signboard | Body-Writing
                            SBPR: Loaders

                            CM3D2 HF Patch (v120.0)
                            CM3D2.ToolKit - Pre Release

                            Comment


                            • #15
                              Originally posted by usagirei View Post
                              Where is the game install located?
                              D:/KISS/CM3D2/

                              Comment

                              Working...
                              X