Friday, September 2, 2016

Troubleshoot access violations using specific ImageBase address on libraries


Nothing more frustrating than an Access Violation error on a program compiled without managed code.
If you have worked with Delphi or C++ you know what I mean. 
To make things even worse, you may have to refrain from using unhandled exception managers for different reasons, most often than not security. This is a common situation for installed software.
Many organizations see stack dumps as security holes in applications that can be used to facilitate cracking of the software.

How can you make troubleshooting easier if you don't have an exception manager capturing the full call stack?

A common technique used implies compiling your app with source code matching production, and then using your debugger tool to navigate to an specific address in memory. Different debuggers will offer different ways to do this.

In the case of Delphi there's at least a couple of ways:
  1. Use the main menu Search|Go to address... option
  2. Or, use the CPU/Assembly view, right click anywhere on the assembly view and select Go to address... context menu
Either way, this works... sometimes...

The problem is that any time you create a new project with an IDE, there's a project setting that goes often overlooked that is created always with the same value. The default value.
This setting is the "Image Base" of the binary you will be producing.

What is the Image Base?


In short, it's the address where a module will *tried* to be loaded. See the following articles for details:


The issue here is that if this setting is left unchanged, the OS will "relocate" your binary when it's loaded as the default address will likely be used by another module. 
Of course when this happens, the likelihood that the binary is loaded at an address that matches the one in your machine where you intend to run the debugger is slim. You will do a Go to Address... punch in the address you got from your error message and most likely you will end up in lalaland.

To clarify, the address I mean you need to use to try to trace the location on the error is the highlighted in yellow below:



Now, if you set the ImageBase of your binary to something unique and acceptable (the value must be multiple of 64K), using Go to address... you will get to the exact place in the code (asm or source) where the error happened as long as the module was loaded in the same location while debugging.


Click OK, and you end up here:



As you can see, the memory address of the particular assembly instruction is highlighted, and it happens to be a few asm instructions below the line of code that generated the Access Violation:

s := PString(nil)^;


Where to do you change this ImageBase in your IDE?


Delphi:




In Visual Studio:



Hope this helps you with your Access Violation adventures.

Enjoy

Thursday, September 1, 2016

Running dynamically generated code in C# (Part 2)


In Part 1 of this topic I shared a GitHub repo that compiles code snippets in real-time, loads them as an assembly for execution.
A problem with this approach, widely discussed online, is that the assembly containing the code will be loaded in the currently running AppDomain making the newly loaded assembly impossible to unload.
In many cases this is not a problem, particularly on cases where the number of different instances generated code if finite and manageable. You can simply cache this "scripts" in memory and reuse them later when needed.

What about the cases where we don't want to clutter the memory and our main AppDomain with an ever growing list of dynamically generated assemblies?

Well, for those cases, luckily there's a way to unload the dynamic code, but it comes at a heavy cost.
Let's review what needs to happen to achieve this;

  1. The dynamically generated assembly must be loaded in a separate AppDomain instance
  2. The calls from the main AppDomain to the AppDomain hosting the dynamic assembly must be marshaled using MarshalByRefObject. This mean we will incur in about 20x performance degradation on the call itself vs. calling a method directly.
  3. To avoid serializing objects for sharing with the "script", a hack can be used casting an object's memory address to an IntPtr and back within the dynamic assembly. In order to do this, the following has to be done:
    1. Shared objects between main AppDomain and the AppDomain hosting the dynamic assembly must be compiled into a strong named assembly (signed) and installed into .NET GAC using gacutil tool.
    2. The host application must run with the attribute instructing to use LoaderOptimization set to MultiDomainHost
    3. The dynamically generated assembly should be loaded with MultiDomainHost option.
    4. If running the app on the IDE for debugging purposes, the option to let Visual Studio host the application must be disabled 

Without further due, the latest version of the repo has the code updated to enable running the "scripts" using a separate AppDomain and show how these dynamic assemblies can be unloaded.

That's it for now.