Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BadImageFormatException when using it injected #3

Open
Jarrekstar opened this issue Feb 3, 2017 · 4 comments
Open

BadImageFormatException when using it injected #3

Jarrekstar opened this issue Feb 3, 2017 · 4 comments

Comments

@Jarrekstar
Copy link

Jarrekstar commented Feb 3, 2017

Hi,

I have a test WinForms application built in .Net 4.5/Release config. The assembly I inject into it is also built against .Net 4.5 in release config. Now I have no problems getting types from the host winforms app, I can even do the example in the sample app where number 1 and 2 gets compared and the < operator gets changed to >.

Both my methods are static and public. When I try to modify the method by completely exchanging it with another one with the same signature/name/etc except having the compare operator reversed, I get a BadImageFormatException when invoking the method (the InjectionHelper.UpdateILCodes throws no errors whatsoever). This scenario works without problems in the sample application.

Can you give me some hints/tips/insight on how I could fix this?

Thanks in advance,
Jarrekstar

@Martmath
Copy link
Owner

Martmath commented Feb 6, 2017

Hi.
If you send a sample project with the error to martmath0@gmail.com, i will try to watch it this\next week.

@Jarrekstar
Copy link
Author

Jarrekstar commented Feb 6, 2017

Hi,

Thanks for the quick reply!
I've attached the projects. Basically you just have to run FormsTarget.exe, press the button if you want to see that the default method works fine, then start the Loader which will inject the assembly with the modified method into the target. When you press the button again, you should get the exception.

IL_Code_Injection_Test.zip

Thanks a lot in advance,
Jarrekstar

@Martmath
Copy link
Owner

Martmath commented Feb 19, 2017

Hi, sorry I don't know the inner workings .net but as I understand, the problem is in metadatatokens (mdt in next texts). I explored an example of the methods, but for fields and types, I think everything is similar (there are a few differences for “static strings”). Link with your assembly (asbl next text) is not enough for using your code in another application.
You need at least one direct calling of injected method (don’t sure about field or type) your asbl from being modified asbl. So your method will get a new mdt in another asbl. It differs from the mdt used in native asbl or, for example, in the code generated by CsharpCodeProvider. MetadataToken property every time return direct mdt, so I used my RealTokens class instead MetadataToken. I don’t see the way for using this class in another asbl –only deep searching in methods code by using some about “Assembly.GetTypes()[0].GetMethods()[0].GetMethodBody().GetILAsByteArray()”. But if u found how add tokens without direct calling/referencing, it is interesting for me too.
But...if reflection (System.Type.GetType(), System.Type.GetMethod(), System.Reflection.MethodBase.Invoke ()) has been used in another assembly,
you can try to call a method without tokens. To do this:

  1. Note that the call will be longer (20 bytes or 21 for not Public / Instance vs. 5 bytes) –So your il code should be shorter, or you have to use the other longer method in another asbl for copy and changing code. After calling this method you should return the original code.
  2. For type and method names is necessary to find a method with two input string parameters (full count and type of another input parameters are not famous. Use null / Default (type) for them in invoking method which we change) ... or object type + using call .ToString () inside our il code instead string type.
  3. One string input and two string class variable can help u, instread of second item.

As u see, u have many "if" for using this way and u can use only native data (types/methods/static string) without problems.
You can go another way. Call methods other asbl from your asbl. So you can easily use reflection or arrange batch loading (calling) of the other asbl methods through t4 + reflection, for example. But it is necessary to understand the need to replace everything mdt, when refactoring other asbl method. Also you will get big problems with UI - will have really regenerate it from scratch.
Also wish to see the profit of using CsharpCodeProvider and add both assembly to ReferencedAssemblies.

@Jarrekstar
Copy link
Author

Jarrekstar commented Feb 20, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants