Is this line of code from ILSpy decompiler valid? - c#

I decompiled a release assembly using ILSPy and I got code like below. When I open the decompiled project in VS 2013, I get an error for each of these statements.
using #j;//this line shows up as an error in VS2013
using System;
The error is:
Preprocessor directives must appear as the first non-whitespace character on a line
I get a similar error at following line also.
string path = #db.#ab(HttpUtility.UrlDecode(text));
Question : What is the meaning of using # and how can I correct these errors?
I have also noticed that some decompiled classes have names starting with # and so do some namespaces and method names. I have never used such a naming convention, so it's very confusing how 'ILSpy` came up with such code.

No, it's not valid C#. Chances are it's decompiled code that was obfuscated to start with, so using identifiers that are valid in IL but not in C#.
Typically, if you're decompiling obfuscated code, you're doing something against the wishes of the original authors of the code - so I'd suggest just not doing that. If you think you have a legitimate reason for getting the source code for something, ask the author.
Could you convert this into valid C#? Sure - just take every #-prefixed identifier, and map it (consistently) onto something else, e.g.
using hashj;
...
string path = hashdb.hashab(HttpUtility.UrlDecode(text));
... and eventually you'll run across a class called #db which you'd then rename to hashdb etc. But the point of the obfuscation is to make this a painful process.

Related

Does my code inside preprocessor directives included in compiled code if the directive is not present in c#?

I have an application which I want to create a demo for it. I prefer to give another exe for my paid version and different one for demo to prevent people with demo version to crack my paid version. For now I have commented the code I need in demo so whenever I have to create a demo I go over these comments and make the necessary changes. Today I realize the #if directive..
Now my question is if I have a code like this
#if DEMO
public string test()
{
return "blabla";
}
#endif
and I did not define DEMO directive, so my code gets greyed out obviously and I can't reach this method which is what I was expecting so far. Now I have rebuild my project without defining DEMO directive and I deleted my .pdb file from output folder after that I tried to check my executable with dotpeek and I could not see this test method there.
Can I use this approach to separate my demo and paid version executables? Lets say this test method is a demo method so it wont be seen in paid version if someone cracks it. And same goes for opposite, if this test method is a paid version method and I put it inside #if !DEMO then if I define DEMO and rebuild my exe I won't see this test method there right?
As I mention before I already checked the code and could not see my methods with dotpeek but I just want to be 100% sure that these methods wont seen in programs like dotpeek or anywhere else
Yes, the code is completely omitted if the symbol isn't defined. It can be absolute garbage code - the compiler ignores it completely; it just looks for the end (either #endif or #else).
The question about whether that suits your needs for demo/paid versions is somewhat different, but the answer from the technical perspective of "what gets included in the output" is simple.

Provide hint to IntelliSense that a partial class should not be modified

As of lately I'm using quite some code generation, usually in combination with partial classes. Basically the setup is as follows:
Partial class containing generated code. Some of this code will call partial methods. The code is re-generated a lot of time. The code generator is in some cases a custom tool.
Partial methods are manually implemented in a separate file.
The problem is that when I'm using Intellisense features like "generate method", they are for some reason generated in the file containing the generated code. Obviously I don't want that.
My question is: Is it possible to generate some hint that tells Intellisense it shouldn't touch certain 'cs' files (but instead the other partial class)?
Update
In retrospect I should have noted that I'm using a custom tool to generate the code. It's not a EF or a simple transformation; there's quite a bit of logic involved in the code generation. Also, it generates a complete namespace and class structure with partial classes. The 'root namespace' is found by extracting it from the csproj file and then using the folder structure to figure out the absolute namespace (it's similar to how Linq2sql does this).
The answer suggested by xanatos (thanks!) works: intellisense sorts its operation on the name, then alphabetically sorts on the name and then picks the first item in the list. This means that you can generate a zzzz.foo.cs which (albeit a bit ugly) will work just fine. I've just ran some experiments and found out that the feature find all references returns the order that VS appears to use. As it turns out, it works like this:
Say you have a custom tool that works on the filename foo.bar and transforms it into foo.cs. The custom tool will generate the content as string and pass it back to Visual studio (that's just how custom tools work...). The result will be in a file called foo.cs.
Now, I was quite surprised to found that Intellisense does not sort it as foo.cs but rather as foo.bar\foo.cs. In other words: regardless of how you name the 'cs' output in your custom tool, you have to rename the base file foo.bar to something like zoo.bar.
While that might be a workaround, I'm hesistant to accept it as the answer, because I would have to give files in my project strange names (names have meaning...). Also, some of my custom tools have dependencies on their filenames, so that will also get broken...
Therefore, I'm still open for suggestions on how to fix this properly.
From a simple test I've done in VS2013, it seems that Visual Studio 2013 adds the method to the "first" file he finds in the Solution Explorer. So you could simply add a .something.cs to your file-name, like MyClass.generated.cs vs MyClass.cs. Be aware that the VS2013 seems to be using the "full path", with path ordering based on name. So:
Z\MyClass.cs
comes after
MyClass.generated.cs
(and Intellisense will put code in MyClass.generated.cs) even while in the Solution Explorer all the folders are ordered first.
Full example:
A\MyClass.gen3.cs
MyClass.gen2.cs
Z\MyClass.gen1.cs
This should be the order as "seen" by the Intellisense, so it will put the new classes in A\MyClass.gen3.cs.
Assuming you're talking about the EF, I always change the template file (.tt) so the filename of the auto-generated file is [classname].model.cs. This means my partial file, which by convention is called [classname].cs is alphabetically first and always seems to get picked for auto-generation.
All you have to do is find/replace all the:
fileManager.StartNewFile(entity.Name + ".cs");
With:
fileManager.StartNewFile(entity.Name + ".model.cs");
There should be 3.
This has other benefits like auto-generated files are clearly marked in the filename.
I still have no idea why they didn't do this in the first place.
If you're not talking about the EF, the same trick of using the filename to order them should work.

How to replace global string before compiling in Visual Studio

Every time I compile my application, I would like to replace a string such as $(Database) with [DatabaseName] in all files within my solution/project.
I looked at Pre-build events and Macros, but cannot figure out how to add my own key value pair to it. The solution has many sql files that are in need of replacement of a particular variable. Can this be done via RegEx? I know I can do a FindAll/ReplaceAll but that does not address the issue of doing this over and over.
Okay, so this probably isn't the best solution, but I think it's gonna be better than trying to find some sort of internal solution to replace all instances of a non-code string at compile-time.
The idea is preprocessor directives. You can use the # operator on any line to add a preprocessor directive like so.
One is if/elif/else:
#if DEBUG
// Access your test database here
#else
// Put your hard-coded database calls in here.
#endif
This way, any build of the Debug branch will execute on your test code, and any Release build will execute the original hard-coded database calls.
You can also use your own custom values with #define, like #define MYTESTVARIABLE, after which sections wrapped in #if TESTVARIABLE ... #endif will execute.
Here's the MSDN page: http://msdn.microsoft.com/en-us/library/ed8yd1ha.aspx
As I said, this isn't the best option - it definitely increases the amount of code - but I think it might be less brittle than where you were going in your head.
In SQL Server or ORACLE you could use CREATE SYNONYM to set the name in code so that the code base always references the same name forever so that you do not have to change your code, you just create a SYNONYM on each server for each table or object.
In all cases like you describe I have found a way without using SYNONYM to remove the need for the code file changes during compile. Thus not needing to ever actually use synonym in situations like you describe. I am recommending you take a different approach to the problem. Try not to modify code on each compile. Usually a config file or runtime tweak is all that is needed.
Also be aware that you may see in generated files "MyDevDatabaseActualName" but in reality you do not have to replace it with the QA or Prod database name. This name you are replacing is a TypeName that was chosen from your initial database connection and only a config file change is needed to point to a new database.

Emacs 'csharp-mode' Byte Compilation Error

When I attempt to byte compile csharp-mode under Emacs 24.2.1, I am getting the following error:
csharp-mode.el:2028:1:Error: Symbol's value as variable is void: csharp-enum-decl-re
This post confirms this same compilation problem and offers the following remedy:
I tried manually defining csharp-enum-decl-re by doing C-x C-e on the
defconst; this got it to compile.
This remedy worked for me as well! However, this remedy leaves me with a couple of questions:
Without pre-defining csharp-enum-decl-re, why does csharp-mode.el fail to byte-compile? (See the first link for the source code for csharp-mode.el.)
Without modifying csharp-mode.el, is there a better workaround for this compilation problem?
The error indicated at line 2028 concerns the following definition. Where is the dependency on csharp-enum-decl-re?
(defconst csharp-font-lock-keywords-2 (c-lang-const c-matchers-2 csharp)
"Fast normal highlighting for C# mode.")
To the best of my knowledge:
The file fails to byte-compile because a macro needs the value of a symbol that has not been defined. This error slips to some programmers because they are developing with an emacs session where they have eval'ed some of the code they are writing. A typical solution to the compilation error is to use eval-and-compile macro for those expressions needed to know at compile time.
Using eval-buffer before byte-compile is a workaround that saves you from modifying the source. Writing a patch and sending it to the author is another option.
Code is relatively tricky because of it relies heavily in macros. c-lang-defconst is suppose to define values for c-matchers-1, c-matchers-2 and c-matchers-3, but for c-matchers-2 the value of csharp-enum-decl-re is needed (see line 1304). Note that the name of the symbols (c-matchers-*) are created by the c-lang-defconst macro itself.

Rename de-obfuscated code

Is there any tools that can rename de-obfuscated code to readable code for .NET dlls ?
OBFUSCATION = convert original variable names, namespaces to non-readable variable name, also changing the control flow to make it hard for crackers to guess the original code
DE-OBFUSCATION = reverse process of obfuscation. convert non-readable variable names, namespaces to readable one like A1, A2 (cause converting back to original names is impossible) make it easy to track and understand the original source code.
You could obfuscate it again, but disable options like overloading. That way members will be named A,B,C,... instead of all being named A (using overloading) or having non-printable names.
Also, an IL-level optimizer can often undo control flow obfuscations and remove dead code designed to crash decompilers.
Once you have compilable code, use Visual Studio's rename refactoring to introduce names. There's no way for tools to automatically guess appropriate names.
No there isn't otherwise why would obfuscation tools exist in your opinion? What you call readable variable names no longer exist in the obfuscated assembly because they have been renamed to non-readable ones and no tool could guess what the original names were.
do you mean looking at code within complied dlls? if so i use redgate's .net Reflector.

Categories

Resources