I'm trying to change a method in a compiled C#-asp.Net web application. is it possible to somehow override a method inside a compiled dll ?!
I did reflect the dll, but it has tons of references and has been referenced tons of times, so I do not think, even if it is possible because of the hundreds of errors in Visual Studio, recompile the dll would be a good soloution.
Basically what I need to do is to change a FormatDateTime method inside a core dll to add support for an unsupported calendar (date format).
and of course I have access to the server of the application, and I can do what ever I want in Administrator level.
can someone guide me in a direction ?!
You can override the method only if it is virtual, and it doesn't matter whether you do it through reflection or statically.
It think that the best thing you can do is use a decompiler and fixe the code in MSIL. Then you can generate a new assembly from the MSIL.
For a decompiler, you can use the Telerik JustDecompile is simply awesome: http://www.telerik.com/products/decompiler.aspxI
Related
I have a DLL written in C# for which I don't have the sources. I have tried different C# decompiler to modify the DLL, but they all give me errors in my attempts to recompile with the modifications, I suppose due to IL decompilation limitations. Is it possible to add a .cs file to the root of the DLL in order or inject a method to add a functionality ?
PS: This is not intended to hack a software but to create a mod of a game which requires DLL modification.
Your best approach may be to just create a wrapper project around the dll to add the functionality that you want. Your code could them reference the project instead of the dll. As long as the classes aren't sealed you should be able to inherit from them.
Modifying code you don't have access to probably isn't a good idea to begin with. Especially if the dll could be updated in the future.
You can also create a new DLL with the same namespace. This might make things look as if they're in the same location, but it's not the best practice and it could be confusing since namespaces are expected to match the project/dll name.
Benjamin's solution with the wrapper seems reasonable.
The Reflexil plugin for .NET Reflector could inject a method or a class in a DLL as illustrate in a video by its creator.
It prevents decompilation-compilation errors as it just injects IL code in the assembly.
To install this plugin follow these steps.
I'm wondering if i can change a function in system.dll
like instead of return 0; i change it to return -1;
and recompile it and use it again.
If yes how we can do it ?
No, you can't. You can't because you can't strongly sign the assembly you would produce with the Microsoft signature, and so all the other assemblies that reference the System assembly would complain (I know this because two weeks ago I tried to do something similar :-), but I didn't want to recompile. For me it was enough to use Mono.Cecil to directly edit a copy of the System assembly)
If you are writing unit tests, you could use Fakes (requires Visual Studio Premium). It let you redirect methods of an assembly to your code, controlling the output and what the method does.
Technically you could do what the Fakes "library" does with this: http://www.codeproject.com/Articles/453065/ILRewriting-for-beginners But note that it is complex. You create a "runner" for your exe in C/C++. This "runner" (it is technically a CLR Host) can rewrite "on the fly" the .NET code of an assembly.
I have a c++/CLI library that is in turn calling a c# library. That is fine, it is linking implicitly and all is good with the world. But for various reasons the libraries are not getting quite the prefect treatment by our automated build process, and the libraries are not finding each other unless we move the libraries to locations that we would rather not have them in, and would rather not fold into our build process.
It is suggested to me that we/I could write a post-build event that uses XCOPY. but lets say we don't want to do that.
Another suggestion is to explicitly load the dll. Windows says that to link explicitly "Applications must make a function call to explicitly load the DLL at run time." The problem is that Microsoft's example is not enough for my small mind to understand how to proceed with this idea. Worse, the only example I could find is out of date. Perhaps I am not using the right search terms but I am having difficulty finding more about it with google.
How do we explicitly Link a c++/Cli Library to a C# .dll?
----edit
OK, How do we explicitly Link a C++/CLI code, which exports a library using __declspec(), to a C# .dll.
There is no such thing as a "C++/CLI library", only assemblies are supported. There is no explicit or implicit linking, binding always happens at runtime. Assemblies are found at runtime by the CLR, the rules it uses to locate them are described in detail in the MSDN library.
Copying all dependencies into the same directory as the EXE is the sane way to go about it while you are developing the code. Well supported by build system, the C# and C++ rules are however different. C++ projects build to the solution's Debug directory, C# projects build to the EXE project's bin\Debug directory. So yes, altering a C++ project's Output Directory setting or copying files with a post build event is usually required to get everything together.
What's the point of dynamically loading an assembly? Isn't it just way simpler to just reference it in your solution/project, saving you all the calls to Assembly.*Load* functions?
Update: Is it useful outside of plugins? What about exclusively in web development, what uses would I find there for dynamically loading an assembly?
Dynamically loading an assembly is useful for anything requiring execution of external code that might not even exist when the hosting program is developed.
For instance, any plug-in system will have to use that feature.
What if you want to make it possible to write plugins for your application, which get loaded at runtime and you don't have that project at compiletime?
You may not have that assembly when you compile your code, think of plugins for instance. You can't compile with a reference to them. Other reason is generating and compiling code and then loadin that Advanced stuff but real use.
GJ
I'm getting System.IO.FileNotFoundException: The specified module could not be found when running C# code that calls a C++/CLI assembly which in turn calls a pure C DLL. It happens as soon as an object is instantiated that calls the pure C DLL functions.
BackingStore is pure C.
CPPDemoViewModel is C++/CLI calling BackingStore it has a reference to BackingStore.
I tried the simplest possible case - add a new C# unit test project that just tries to create an object defined in CPPDemoViewModel . I added a reference from the C# project to CPPDemoViewModel .
A C++/CLI test project works fine with just the added ref to CPPDemoViewModel so it's something about going between the languages.
I'm using Visual Studio 2008 SP1 with .Net 3.5 SP1. I'm building on Vista x64 but have been careful to make sure my Platform target is set to x86.
This feels like something stupid and obvious I'm missing but it would be even more stupid of me to waste time trying to solve it in private so I'm out here embarrassing myself!
This is a test for a project porting a huge amount of legacy C code which I'm keeping in a DLL with a ViewModel implemented in C++/CLI.
edit
After checking directories, I can confirm that the BackingStore.dll has not been copied.
I have the standard unique project folders created with a typical multi-project solution.
WPFViewModelInCPP
BackingStore
CPPViewModel
CPPViewModelTestInCS
bin
Debug
Debug
The higher-level Debug appears to be a common folder used by the C and C++/CLI projects, to my surprise.
WPFViewModelInCPP\Debug contains BackingStore.dll, CPPDemoViewModel.dll, CPPViewModelTest.dll and their associated .ilk and .pdb files
WPFViewModelInCPP\CPPViewModelTestInCS\bin\Debug contains CPPDemoViewModel and CPPViewModelTestInCS .dll and .pdb files but not BackingStore. However, manually copying BackingStore into that directory did not fix the error.
CPPDemoViewModel has the property Copy Local set which I assume is responsible for copying its DLL when if is referenced. I can't add a reference from a C# project to a pure C DLL - it just says A Reference to Backing Store could not be added.
I'm not sure if I have just one problem or two.
I can use an old-fashioned copying build step to copy the BackingStore.dll into any given C# project's directories, although I'd hoped the new .net model didn't require that.
DependencyWalker is telling me that the missing file is GPSVC.dll which has been suggested indicates security setting issues. I suspect this is a red herring.
edit2
With a manual copy of BackingStore.dll to be adjacent to the executable, the GUI now works fine. The C# Test Project still has problems which I suspect is due to the runtime environment of a test project but I can live without that for now.
Are the C and C++ DLLs in the same directory as the C# assembly that's executing?
You may have to change your project output settings so that the C# assembly and the other DLLs all end up in the same folder.
I've often used the Dependency Walker in cases like this; it's a sanity check that shows that all the dependencies can actually be found.
Once your app is running, you may also want to try out Process Monitor on the code you are running, to see which DLLs are being referenced, and where they are located.
The answer for the GUI, other than changing output settings, was the addition of a Pre-Build Step
copy $(ProjectDir)..\Debug\BackingStore.* $(TargetDir)
The answer for the Test projects was to add the missing DLL to the Deployment tab of the testrunconfig. You can either do so by directly editing the default LocalTestRun.testrunconfig (appears in Solution under Solution Items) or right-click the Solution and Add a new test run config, which will then appear under the main Test menu.
Thanks for the answers on this SO question on test configurations for leading me to the answer.
The reason why this happens is because you either are loading DLLMAIN from managed code, before the CRT has an opportunity to be initialized. You may not have any managed code, be executed DIRECTLY or INDERECTLY from an effect of DllMain notifications. (See: Expert C++/CLI: .Net for Visual C++ Programmers, chapter 11++).
Or you have no native entrypoint defined wahtsoever, yet you have linked to MSVCRT. The CLR is automatically initialized for you with /clr, this detail causes a lot of confusion and must be taken into account. A mixed mode DLL actually delay loads the CLR through the use of hot-patching all of the managed entry point vtables in your classes.
A number of class initialization issues surround this topic, loader lock and delay loading CLR are a bit trickey sometimes. Try to declare global's static and do not use #pragma managed/unmanaged, isolate your code with /clr per-file.
If you can not isolate your code from the managed code, and are having trouble, (after taking some of these steps), you can also look towards hosting the CLR yourself and perhaps going through the effort of creating a domain manager, that would ensure your fully "in-the-loop" of runtime events and bootstrapping.
This is exactally why, it has nothting todo with your search path, or initialization. Unfortunately the Fusion log viewer does not help that much (which is the usual place to look for .NET CLR assembly binding issues not dependency walker).
Linking statically has nothing todo with this either. You can NOT statically link a C++/CLI application which is mixed mode.
Place your DLLMAIN function into a file by itself.
Ensure that this file does NOT have /CLR set in the build options (file build options)
Make sure your linking with /MD or /MDd, and all your dependencies which you LINK use the exact same CRT.
Evaluate your linker's settings for /DEFAULTLIB and /INCLUDE to identify any possiable reference issues, you can declare a prototype in your code and use /INCLUDE to override default library link resolution.
Good luck, also check that book it's very good.
Make sure the target system has the correct MS Visual C runtime, and that you are not accidentally building the C dll with a debug runtime.
This is an interesting dilemma. I've never heard of a problem loading native .DLLs from C++/CLI after a call into it from C# before. I can only assume the problem is as #Daniel L suggested, and that your .DLL simply isn't in a path the assembly loader can find.
If Daniel's suggestion doesn't work out, I suggest you try statically linking the native C code to the C++/CLI program, if you can. That would certainly solve the problem, as the .DLL would then be entirely absorbed into the C++/CLI .DLL.
Had the same problem switching to 64-bit Vista. Our application was calling Win32 DLLs which was confusing the target build for the application. To resolve it we did the following:
Go to project properties;
Select Build tab;
Change 'Platform target:' option to x86;
Rebuild the application.
When I re-ran the application it worked.