1 Jul 2011

Change of face

Well, it has been a while since a post has found it's way onto this blog. I've been meaning to re-ignite it but as per usual life feels like it should take precedence.

Long story short - I'm not re-igniting this blog as a development blog. Instead, I'm breaking up my personal blog and development blogs accordingly:

  • blog.threesacompany.com - This will be where I'll post all of my development "lessons", thoughts or musings. No real theme as such, but more what tickles my fancy at the time. At the moment this would likely be Objective-C, iOS, Ruby on Rails, C++ and maybe a bit of C# here and there.
  • paul-mason.posterous.com (NB: did use to be blog.paul-mason.co.nz but have since revoked the domain) - This will include personal musings not related to work items. This will probably include thoughts and musings about business, art, veganism, sport, lifestyle or anything that tickles my fancy at the time.

So! A change of face - if you're interested in development then switch blogs, if you haven't already :-) Otherwise expect some vastly different topics here!

In the meantime I'm going to do a shameless plug: a bunch of business people here in Tauranga have (as of today) launched a new charitable trust called 4Good. The purpose of this site is to make giving to charity easy (sort of like giving with training wheels) - we do this by accepting a $4 donation each month (a price of a coffee) from our members. Of this $4, 100% goes towards the chosen charity for that month - for the first month (i.e. July 2011) this goes towards the Child Cancer Foundation.

So check it out - and if you feel so inclined, pass on your morning coffee for today and instead give it to a very deserving charity :-) The website is http://4good.org.nz - check it out! 

20 Apr 2011

How to write a blog post in 140 characters or less

6 Dec 2010

Converting a Boot Camp partition to a Virtual Image

Maybe I was looking under all of the wrong rocks, however I struggled converting my Boot Camp partition to a virtual image. I tried:

  • Downloading VMWare Converter and running it under Boot Camp
  • Running VMWare Converter under a virtualised Boot Camp
  • Attaching the disk to another machine and editing the partitions manually
  • etc...

I was about to give up when I noticed an import button appear in VMWare Fusion when the Boot Camp partition was highlighted... I clicked on that and lo and behold it worked first time!

Maybe it's obvious and I simply thought it was harder than it should have been (from what I read online), but in reality - it was right in front of me the whole time! Perhaps the VMWare Fusion interface needs improving and simply disables the button if it is not available?

Anyway, hopefully this helps save someone a few hours that I unfortunately lost!

30 Sep 2010

Entity Framework Observations

I've had the joy of working with the Entity Framework the last few weeks for a project I'm working for. I decided to write down some of my observations of the suitability, advantages and disadvantages of the framework. I am a little biased with what an ORM should be like; in my opinion Mindscape Lightspeed is really what others still hope to be like, however occasionally it isn't the correct fit for the project due to it's commercial nature (though in my opinion the cost is minimal compared to developer savings!).

Suitability

The Entity Framework was chosen for this project for a few reasons:

  • It's free
  • It is Microsoft endorsed
  • It is flexible in regards to a configuration over convention approach
  • It is enterprise "ready"

This particular project had originally had a SubSonic 3 "hack" in place, however that was completely the wrong tool for the job. For small projects it may be OK however it is still too premature in development stages for being enterprise ready: it is filled with bugs in it's LINQ implementation and has many shortcomings.

In this case - the Entity Framework is an appropriate tool for the project.

Good Things

The Entity Framework has many good things going for it!

  • Flexible - it is extremely easy to map a mixed standard database over. It doesn't rely on convention at all.
  • Strong LINQ support - it is nice to know that LINQ "just works" as opposed to finding "Not Implemented" errors!
  • Strict rules - can be a good or a bad thing - in this case it is good. It means that your database has all the necessary relationships/indexes etc ensuring it performs well!
  • Used by Microsoft - got to be a good thing! Means that the technology won't be a passing fad. Although appropriate design still goes a long way to make sure that if it does it won't be SO bad to fix.

Bad Things

So there are a few bad things with the framework too:

  • The models cannot be split into multiple files (i.e. linked models) - for a big project it'd be nice to split models into small chunks. It is really just so that we can isolate changes and speed up model navigation.
  • Enumerations are not supported - why not? It should be a pretty trivial thing to generate an enumeration with a base type of short or int!
  • The designer is buggy - there are many times where a refresh will generate duplicate relationships which then completely screw up the model!
  • Model refresh cannot be isolated - what if I create a new foreign key on one table. Why do I have to refresh the entire model? This wouldn't be such an issue if the designer wasn't buggy!
  • The EDMX files are confusing - maybe it's just the shear size of it, but manual changes are not as easy as they could be!
  • Error messages are confusing - unfortunately it can be a matter of trial and error figuring out the issues the model has! Once you figure out why the error is happening, fixing it isn't so bad - but diagnosing can be tough.

Wrap Up

This is really just a short observational post based on my experience with the Entity Framework over the past two weeks. It is really only brushing the surface - I could list many more features that I've come to expect from using Lightspeed that just aren't present in EF4.

Anyway, I really hope they can fill a few of the shortfalls that it has (preferably before the release of EF4). While they aren't showstoppers - they are very annoying. Given the choice, I'd still swing to Lightspeed any day!

UPDATE: I've been informed that EF4 was released with VS2010 and it is only a POCO adapter and code only extensions that are in CTP at the moment. I guess we'll have to wait for EF5 then... Thanks JD for the heads up!

If anyone has anything to add then feel free to post a comment.

13 Sep 2010

Hiatus

I've had quite a break from blogging - and an unintentional one at that! Due to personal circumstances I cut writing down to nil. Well, that's not quite true however from a public perspective it may as well be!

After all that, I'm back however with a different hat on so to speak...

Why aren't you doing IP protection?

I realised one blog post, that the time for me to write a post was becoming more and more intensive. Some posts would take me over a day to complete chunk by chunk which in turn was detrimental to other growth development that needed completing. I quickly realised that I was not "selling" my development byproduct (I rarely deal with IP protection day to day), but rather creating an entirely new development focus. Because of this, each blog post was taking more time than it needed to, which in turn started to affect my other commitments. Herein, the posts will be related to my everyday experiences - hopefully this will make more efficient use of ever valuable time.

What can I expect?

The posts will remain high quality topics. I will actively note down anything that interests me in my day to day work from development to development process to business process. I'll try to post something here at least once a month, ideally once a fortnight. If I don't have the notes for a topic that month then that will indicate to me that I'm in a serious need to relook at the type of work I'm doing!

In saying that, I don't have a topic down as of yet, however I expect to get one up as soon as one pops up.

So all in all - I'm back! I look forward to sharing my knowledge with you all again.

21 May 2010

Rework - a smidgen different than before

I was at a friends house the other day and he handed me a book. "You've gotta read this - it's written by the guys from Basecamp and... well just read it." Intrigued, I put the book in my napsack (sounds better than in my pile of papers) and took it home with me. I put it on my desk and then went about my day. It stayed sitting on my desk for a couple of days, partially forgotten, and then a strange twist of fate (a rainy Sunday) made me pick it up and start reading.

As soon as I started reading, I couldn't put it down. I tried... twice. However before I knew it I had read it cover to cover. This isn't quite as cool as it sounds as the book is padded a bit with illustrations however don't let that fact distract you from the quality of the content.

The book I'm talking about is Rework written by the founders of Basecamp.It is essentially a list of micro tips that the authors have discovered while building their business. And to be quite honest, it is very insightful. I found a lot of value between the two covers of the book; it all seemed to sit well with me based on my previous and current experiences with business. In fact, I've already started implementing some of those lessons in my everyday life - hence this blog post.

Sell your by-products

One of the "tips" that stood out for me (btw there were many, however this one relates to the blog!), was to understand that business production creates by-products. For example, a saw mills by-product is obvious: sawdust. Rather than throw out that by-product they package it and sell it. Waste not want not! The book re-iterated that every business has by-products - even software development companies. The by-product of a software development company may, for example, be knowledge. Why not package that and sell it?

What are you talking about?

Now, I'm not going off to write a book (well, yet!), however I did realise that I need to make my blog more of a by-product of my work. I learn a lot of lessons day to day during development (ASP.NET MVC, C#, Testing, DI, Ruby, Objective C etc) and business therefore I realised that I should start to post more often about lessons I've learnt. This works three-fold:

  1. I get to learn the lesson again
  2. I get to share the lessons for others in that area
  3. I save myself time

An important motivation for this change of direction is the 3rd point - time. My time has become extremely precious lately therefore I want to make sure that the time I have is used in the best possible manner.

What does this mean for your blog?

The reason I started the "Protecting your precious code" series was primarily because I have an interest in the topic of software security and wanted to learn some more. I never use this in my day to day work anymore (well very rarely - largely web-app development), therefore consider it a hobby project. Because it is a hobby project, I haven't had as much time as I'd have liked over the last few weeks to put into it; hence posting has suffered.

Rest assured, this blog is not going to stop - nor am I going to cease posting about security topics! However, I will be posting more often, mixing a lot more of my day to day lessons in there.

What about NCloak?

NCloak will still be maintained however it will be done in my spare time. My goal with this project is to stabalise it and get it ready for production use rather than adding more features after more features. Ideally, it is to make it really good at obfuscation before even considering further enhancements.

Hit me with it

I'm sure this post is going to disappoint a few people, however hopefully it also ignites excitement in many others. It certainly excites me as I love sharing knowledge. As mentioned above, I will not just drop software security from my topics, however moreso update periodically as new information/lessons come to light.

So... hit me with it... thumbs up or thumbs down? Even though I really need to make this decision for the good of myself and this blog I still would like to hear everyones opinions!

P.S. Anyone else read Rework? What lessons stood out for you?

6 May 2010

Migrating to Mono.Cecil 0.9.2

Mono.Cecil was developed by JB Evain back in the fall of 2004 and since has had a fairly stable code base that has changed very little. The world has rather changed around Mono.Cecil... until now! Mono.Cecil has now been updated utilising many compiler features introduced with the .NET framework over the years, fixing many bugs, improving performance, and also improving code flow for developers.

Since NCloak is still in development (with many bugs - thanks to those logging them; I'm getting through them slowly!), I thought it would be a perfect chance to stay on top of the game and upgrade to the shiny new v0.9.2 of Mono.Cecil. This is a breaking version upgrade therefore, as expected, drove me a little insane ironing out all of the introduced bugs in the code! This article is essentially a summary of "gotchas" outside of the migration document to help anyone else performing a migration.

A summary of "gotchas"

I started this post as a diary of the migration process; to be honest it started to get extremely tedious and began to lose usefulness. Therefore, instead I've simply written up a summary of important changes so that it hopefully retains some form of value. Please note, these are notes over and above the migration document already released:

  • Mono.Cecil comes with a "Mono.Cecil.Rocks" library now. This is a very useful library containing extension methods for various objects. It wasn't immediately obvious for me that this existed; I only discovered it when looking for the Optimize() and Simply() methods that used to be on MethodDefinition.
  • ModuleDefinition.Types does not return the full type list anymore! We need to make sure that we call the Rocks extension: GetAllTypes()
  • There is no TypeDefinition.Constructors collection on the type anymore; rather it is all included under the TypeDefinition.Methods collection. This means that you need to filter out constructors where necessary using the IsConstructor property on the method.
  • The architecture of the assembly is now exposed! Check out the Architecture property upon each ModuleDefinition.
  • When creating a new MethodDefinition, the "Body" is not automatically populated with an empty MethodBody. You now have to manually create an instance of this before retrieving any ILProcessor.
  • Some helper functionality (such as saving the assembly to a byte array) has now been removed. Instead each assembly has a Write method which accepts a Stream. To get a byte array, you'd need to write to a MemoryStream and use the ToArray() method from there.
  • Some interfaces have been deprecated; e.g. IMemberReference is no longer present and can be replaced with MemberReference.
  • The ParameterDefinition constructor no longer requires the parameter position to be provided.
  • MethodDefinition.GetOriginalMethod() has been replaced with MethodDefinition.GetElementMethod()
  • FieldDefinition constructors have had their parameter ordering changed (more logical?)

Anything still broken in NCloak?

Unfortunately I couldn't fix everything just yet; there was one area which I believe either needs to be patched within Mono.Cecil or relaxed in NCloak. Currently in our ConfuseDecompilationTask we insert some invalid IL to throw off Reflector and other reverse engineering tools. It is a dodgy method of doing so, however perfectly legal within the framework - well, more specifically overlooked in the framework.

The new version of Mono.Cecil is much stricter than before in regards to faulty OpCodes. We use a framework hack to create an OpCode which is essentially a "nop" in disguise. It appears from initial investigation that Mono.Cecil adds it fine, however internally marks the operand type correctly when added to the IL body - i.e. instead of InlineNone, it may mark it as InlineBrTarget. In itself, this isn't an issue, however when it comes to optimization this causes an exception. The real error is that it has come across a "branch target" without an operand, thus causing a NullReferenceException (Mono.Cecil assumes a branch target has an operand).

So what could we do to fix this? Well, we have two options:

  1. We could perform a check in Mono.Cecil.Rocks to check for a null operand and skip optimization for that instruction or...
  2. We could relax NCloak and choose instructions which aren't branch related (but still short codes).

For the meantime I've just disabled optimization when invalid IL is inserted (works fine), however haven't decided for the long term fix. What do you think it should be?

Conclusion

As expected, we ran into a myriad of issues from upgrading to Mono.Cecil v0.9.2. Most of these issues were simply breaking changes due to member renaming or member functionality changing. While we managed to iron out a lot of the creases from the upgrade we still have a few that we'll get out over the next few irons (I love using metaphors :)).

However, now that we have now upgraded to the new version of Mono.Cecil which means that we can continue stabalizing NCloak bit by bit so that it is ready to be used in real world .NET projects as opposed to in my controlled "laboratory".

Future Episodes

As some of you have noticed the blog posts have slowed down substantially; I am aiming to get at least one post per fortnight at present - more as time permits. Nevertheless, I'm still hacking around when I get the chance therefore will share any interesting information I discover on my journeys.

Last week I put it out there as to what you would like to see in coming articles; I saw the Mono.Cecil v0.9.2 upgrade as a bit of a roadblock therefore now that is out of the way we'll be covering the following:

Definitely
  • Code flow transformations
  • Dead code removal
  • Dispatcher driven tamperproofing
  • Namespace obfuscation
  • Anti-debugging techniques
  • Creating a managed IL parser
  • Bug fixing articles - well interesting ones!
  • Lightspeed tips and tricks
  • Resource Encryption
  • There were also a few "maybe's" which we'll reintroduce in response to demand. As per usual; please feel free to add your opinions!

    Media_httpdotnetshout_zqfed
     
    Media_httpwwwdotnetki_zazgh
    22 Apr 2010

    What would you like to see?

    So, I've been busy lately; so much so that I've needed to put things on hold for this blog. To get back into it, I was going to pick a random topic - really just as a warm up process. So, I went about writing an article. After about an hour and a half into it, somehow my well used computer managed to lose it. Now this is strange as I was writing it online (with supposed auto-save) however it has now disappeared with no sign of it at all. To be honest it wasn't my best piece of work anyway (a sign?). Anyway, rather than write it all out again, I thought I'd come from a different angle:

    What would you, the reader, like to read about?

    I've come up with a few topics that have either been suggested before, or that I've had an urge to write about. What would you like to read about in the next few months?

    • Using Mono.Cecil to automate string decryption decompilation - personally not sure about this one. It can be done, however it would be a "best guess" situation (i.e. find a ldstr that uses a bytearray, work out what method was called and assume that that function is used for decryption).
    • Code flow transformations - maybe a good one once ncloak stabalises a bit more?
    • Dead code removal - yep, we could do this. We just need to improve our mapping process to build a better graph
    • Tamper proofing improvements - we've got a pretty basic implementation in there but it seems weird improving this when the product needs stabalising
    • Dispatcher driven tamperproofing - this is quite an interesting one actually and would be good to have a look at.
    • The .NET hacking toolkit - I started to write this but then realised this is quite a big one. Perhaps draw up a list which can then be added/modified by the reader? Think it'd be useful as I'm pretty old school with this; it'd be interesting to see what's out there.
    • Anti-debugging techniques - I do see the usefulness of this, however the current state of ncloak does make it difficult to implement. Theory only doesn't interest me much... not sure about you guys?
    • Watermarking - could be an interesting one; although I see its usefulness as fairly limited?
    • Creating a managed IL parser - an interest topic really. I've got experience writing compilers, and thought it might be nice to be able to compile IL in memory as opposed to being forced to use the OO approach. Anyone else?
    • Cecil 0.9 migration - A new version of Mono.Cecil is out(!) so this is inevitable. Is it worth writing an article about gotcha's?
    • Bug fixing articles - there are a few bugs in ncloak at the moment. Bugs are always a good chance to learn something :)
    • Lightspeed tips and tricks - big fan of their products and always discovering bits and pieces that make life a lot easier!
    • Build process enhancements - big fan of process/standards!
    • Writing a basic compiler - an interest topic really.

    This isn't an exhaustive list! What would you like to see?

    8 Apr 2010

    Busy Busy Busy!

    You will have noticed a tiny bit of a slow down in posts at present... rest assured - I'm still here!

    Blog will be back to normal within the next couple of weeks... Talk to you all soon!

    13 Mar 2010

    Overcoming the switch statement in IL

    In the last article I mentioned how the community had started using the NCloak application and started finding places where it did not work. The main problems occurred with code injection; before injection it worked fine, after injection we had an invalid program. The last article looked at fixing instruction operand overfow whereby a short form branch statement was now referencing a long form instruction. In this article we take a look at an instruction that I had neglected to fix, and why the fix wasn't as simple as I'd hoped...

    Before I dive into the problem I was having, let's just take a step back and look at code injection and it's implications with Mono.Cecil.

    Injecting Code

    Injecting code is made super easy within Mono.Cecil. Once we have a CilWorker object it is a straight forward process:

    CilWorker il = methodBody.CilWorker;
    Instruction loadSalt = il.Create(OpCodes.Ldc_I4, salt);
    il.InsertBefore(methodBody.Instructions[0], loadSalt);

    Branch statements, as an operand, do not store the "jump to" instruction address, but rather the jump offset from the current instruction. One consequence of injecting code is that we then need to adjust all of the branch style instruction offsets so that they continue to point the correct position.

    For example, if we inserted a NOP instruction then all branch statement offsets before the NOP statement need to increase by one when referencing an instruction after the new NOP statement. Updating offsets is pretty easy; an oversimplified example (well, pretty close to my original code) is:

    //Fix all branch statements
    for (int i = 0; i < body.Instructions.Count; i++)
    {
        //Get the instruction
        Instruction instruction = body.Instructions[i];
    
        //We need to find the target as it may have changed
        if (instruction.Operand is Instruction)
        {
            Instruction target = (Instruction)instruction.Operand;
            OpCode opCode = instruction.OpCode;
    
            //Work out the new offset
            int originalOffset = target.Offset;
            int offset = target.Offset;
            foreach (int movedOffsets in offsets)
            {
                if (originalOffset > movedOffsets)
                    offset += adjustBy;
            }
            target.Offset = offset;
            Instruction newInstr = il.Create(opCode, target);
            il.Replace(instruction, newInstr);
        }
    }

    What could go wrong?

    The switch statement

    The code above was pretty close to what my original code did: adjust all offset pointers for anything which uses an Instruction as an operand. After some more complex testing it quickly became apparent that switch statements didn't work at all. Why?

    Well, switch statements are a little bit different than a normal branch statement as they require a jump to a number of different locations. For example, say you had the following code:

    switch (index) {
        case 1:
            //Do something
            break;
        case 2:
            //Do something else
            break;
        case 3:
            //Do something else again
            break;
        default:
            throw new Exception();
    }

    Within IL, this will get converted into something similar to the following:

    IL_0008:  switch     ( 
                          IL_001b,
                          IL_001d,
                          IL_001f)

    Within each "case", we'll also see the equivalent of break; something like:

    IL_0019:  br.s       IL_0021

    Ok, so the switch statement is just an array of Instructions right? Surely we just do the same as we were doing above, extended for Instruction[] as an operand?

    ...
    else if (instruction.Operand is Instruction[]) //e.g. Switch statements
    {
        Instruction[] targets = (Instruction[])instruction.Operand;
        foreach (Instruction target in targets)
        {
            //Work out the new offset
            int originalOffset = target.Offset;
            int offset = target.Offset;
            foreach (int movedOffsets in offsets)
            {
                if (originalOffset > movedOffsets)
                    offset += adjustBy;
            }
            target.Offset = offset;
        }
        Instruction newInstr = il.Create(instruction.OpCode, targets);
        il.Replace(instruction, newInstr);
    }
    ...

    Well, that was my first thought - but it didn't work! Why not?

    Why can't we adjust and be done with?

    The other characteristic of a switch statement that I wasn't testing for was multiple instructions pointing to the same instruction. The "break" statements within each case were all branching to the same instruction. So why the problem?

    Well, my original thinking was that each branch statement's operand should be uniquely different due to using different offsets. That was until I dived into the Mono.Cecil code. Mono.Cecil is smart enough to realise that these are all the same instruction, thus being in OO land - these all point to the same instruction object. Because my loop was seeing this same instruction multiple times it was also increasing the offset many times causing it to become WAY out of bounds. This would have also been an issue with loop statements with multiple breaks, therefore was a fairly major oversight!

    There was an easy fix to this though...

    The fix

    After realising this I realised that I needed to identify whether or not I'd seen the instruction before. To do this I needed a unique identifier - being in object orientated land I thought about the hash code. After a little testing I discovered that this was being handled correctly therefore could be used as my unique identifier! Thus the fix was fairly easy; the final code is listed below:

    public static void AdjustOffsets(this CilWorker il, MethodBody body, IList<int> offsets, int adjustBy)
    {
        //Unfortunately one thing Mono.Cecil doesn't do is adjust instruction offsets for branch statements
        //and exception handling start points. We need to fix these manually
        if (offsets.Count == 0)
            return;
    
        //We need to make sure we don't fix any instructions twice!
        List<int> seenHashCodes = new List<int>();
    
        //Fix all branch statements
        for (int i = 0; i < body.Instructions.Count; i++)
        {
            //Get the instruction
            Instruction instruction = body.Instructions[i];
    
            //We need to find the target as it may have changed
            if (instruction.Operand is Instruction)
            {
                Instruction target = (Instruction)instruction.Operand;
                int hashCode = target.GetHashCode();
                if (seenHashCodes.Contains(hashCode))
                    continue;
                seenHashCodes.Add(hashCode);
    
                OpCode opCode = instruction.OpCode;
    
                //Work out the new offset
                int originalOffset = target.Offset;
                int offset = target.Offset;
                foreach (int movedOffsets in offsets)
                {
                    if (originalOffset > movedOffsets)
                        offset += adjustBy;
                }
                target.Offset = offset;
                Instruction newInstr = il.Create(opCode, target);
                il.Replace(instruction, newInstr);
            }
            else if (instruction.Operand is Instruction[]) //e.g. Switch statements
            {
                Instruction[] targets = (Instruction[])instruction.Operand;
                foreach (Instruction target in targets)
                {
                    int hashCode = target.GetHashCode();
                    if (seenHashCodes.Contains(hashCode))
                        continue;
                    seenHashCodes.Add(hashCode);
    
                    //Work out the new offset
                    int originalOffset = target.Offset;
                    int offset = target.Offset;
                    foreach (int movedOffsets in offsets)
                    {
                        if (originalOffset > movedOffsets)
                            offset += adjustBy;
                    }
                    target.Offset = offset;
                }
                Instruction newInstr = il.Create(instruction.OpCode, targets);
                il.Replace(instruction, newInstr);
            }
        }
        //If there is a try adjust the starting point also
        foreach (ExceptionHandler handler in body.ExceptionHandlers)
        {
            //Work out the new offset
            Instruction target = handler.TryStart;
            int hashCode = target.GetHashCode();
            if (seenHashCodes.Contains(hashCode))
                continue;
            seenHashCodes.Add(hashCode);
    
            int originalOffset = target.Offset;
            int offset = target.Offset;
            foreach (int movedOffsets in offsets)
            {
                if (originalOffset > movedOffsets)
                    offset += adjustBy;
            }
            target.Offset = offset;
        }
    }

    Conclusion

    Switch statements were a forgotten instruction during the original write of NCloak. The original take assumed that all instructions that needed offset manipulation had an Instruction object as an argument. From community testing it quickly became apparent that switch statements didn't work.

    The basic fix was to also check for an Instruction[] as an operand, however unfortunately this also did not output valid programs. The problem was due to the break statements generating branches to the same location. Mono.Cecil dealt with branch statements using an Instruction object as an operand which meant that we ended up updating the same Instruction offset more than once. We got around this problem by ensuring that we only saw an Instruction once by using the hashcode as a unique identifier. If we had already "seen" the offset then we could assume that it had already been "fixed".

    The latest release of NCloak includes this fix within the code.

    Other Thoughts

    Obviously testing is an important part of any project, however possibly more importantly is defining an appropriate test surface. Being a part time project at the moment, my test surface has been weak at best. As more people start using the product it is getting much more exposure to scenarios that I haven't thought of, or wouldn't think of.

    So far, from the help of the community, I've managed to find three scenarios that I hadn't been testing for (instruction operand overflow, switch statements and instruction reuse), and have another three more I have to fix in the issue tracker.

    If you have a spare moment, run the obfuscator on one of your applications. If you find a bug then please let me know. With your help I can improve this product so that it works the way that you want it to!

    Coming Soon

    In coming articles we will be taking a look at:

    • Using Mono.Cecil to automate string decryption decompilation
    • Code flow transformations
    • Dead code removal
    • Tamper proofing improvements
    • Dispatcher driven tamperproofing
    • The .NET hacking toolkit
    • Anti-debugging techniques
    • Watermarking
    • Creating a managed IL parser

    As always, if you have anything else you'd like to see then let me know!

    Media_httpwwwdotnetki_qpemd
     
    Media_httpdotnetshout_isdue

    Paul Mason's Posterous

    Quirky and creative extraordinaire. Who loves animals. In a good way.