开发者

LINQ causing my obfuscator to break

开发者 https://www.devze.com 2022-12-28 09:26 出处:网络
I have the following LINQ that is causing my obfuscator to break. .Where(f => f.FileN开发者_JS百科ame == fileName).OrderByDescending(f => f.Position).FirstOrDefault();

I have the following LINQ that is causing my obfuscator to break.

.Where(f => f.FileN开发者_JS百科ame == fileName).OrderByDescending(f => f.Position).FirstOrDefault();

Is there another way I could reword this LINQ statement to test against my obfuscator?

I've reported the bug, but it could take 1-2 months to fix, so I need to try recode this LINQ in the meantime.

Update:

The exact cause in the LINQ is :

.Where(f => f.FileName == fileName)


How exactly does the problem manifest? Since the C# expression compiler (used in the LINQ above) uses the memberinfo tokens directly (rather than relying on strings as reflection), I can't see that you could do any better. Likewise, assuming it is an IL obfuscator (not a source obfuscator), re-writing it as a query expression should achieve nothing, nix, zip, zero and nada. You you can try...

var first = (from f in [whatever]
             where f.FileName == fileName
             orderby f.Position descending
             select f).FirstOrDefault();

What exactly happens?


Edit based on comment: if the problem is the "capture", you could try manually building the expression with a constant (instead of a captured value) - where Foo is your type:

    var param = Expression.Parameter(typeof(Foo), "f");
    var body = Expression.Equal(Expression.PropertyOrField(param, "FileName"),
        Expression.Constant(filename));
    var predicate = Expression.Lambda<Func<Foo, bool>>(body, param);

then use:

    .Where(predicate).OrderByDescending(f => f.Position).FirstOrDefault();

The problem, of course, is convincing it that "FileName" and Foo.FileName must stay the same...


And here's a version that doesn't need the string:

    Expression<Func<Foo, string>> liftFileName = foo => foo.FileName;
    var predicate = Expression.Lambda<Func<Foo, bool>>(
        Expression.Equal(liftFileName.Body, Expression.Constant(filename)),
        liftFileName.Parameters);


The solution would be to exlcude the .FileName and .Position properties from obfuscation(renaming).

To avoid having to do this on every query, switch to an obfuscator which supports LINQ-to-* such as Crypto Obfuscator.


In the presence of a broken tool, it is impossible to provide a guaranteed fix. You'll have to tinker with it. Try swapping Where and OrderBy.... Perhaps FirstOrDefault() is breaking, so maybe do that part by hand. In fact, even OrderBy... can probably be replace with a sort. There's a bunch of other stuff you could try.

BTW, Is this LINQ-to-SQL or LINQ-to-Objects? They behave in fundamentally different ways.


Old post, but I had this problem this morning. I'm using .NET Reactor which doesn't natively support obfuscating my POCO's for LINQ to Entities.

If your obfuscator respects the System.Reflection.ObfuscationAttribute, you can use it to exclude your entities and DbContext from obfuscation.

<Obfuscation(ApplyToMembers:=True, Exclude:=True)>

If you have heavier domain objects with other code that you'd like to obfuscate, the minimum exclusions appear to be:

  1. DbContext class name
  2. Property name for each DbSet
  3. Entity class name
  4. Mapped entity properties

In these cases, you only have to use the more lightweight form.

<Obfuscation(Exclude:=True)> Public Property ID As Integer
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号