Check whether a .NET dll is built for Any CPU, x86, or x64

November 16, 2016 Leave a comment

As much as I would like all builds to come from a build server, many times a build comes from a developer’s machine. When I receive a build from another developer’s machine, I need to check if their build is targeting the correct platform.

I can use CorFlags.exe, which is part of the .NET Framework SDK, to find out this information from a dll. Running CorFlags.exe with the file path to the dll will produce the following output:

>> CorFlags "C:\example.dll"

Microsoft (R) .NET Framework CorFlags Conversion Tool.  Version  4.6.81.0
Copyright (c) Microsoft Corporation.  All rights reserved.

Version   : v4.0.30319
CLR Header: 2.5
PE        : PE32
CorFlags  : 0x3
ILONLY    : 1
32BITREQ  : 1
32BITPREF : 0
Signed    : 0

The two fields we need to look at are “PE” and “32BITREQ”.

Any CPU PE: PE32, 32BITREQ: 0
x86 PE: PE32, 32BITREQ: 1
x64 PE: PE32+, 32BITREQ: 0

To programmatically determine the target platform, we can use Module.GetPEKind().

Assembly a = Assembly.ReflectionOnlyLoadFrom(@"C:\example.dll");

PortableExecutableKinds peKind;
ImageFileMachine machine;

a.ManifestModule.GetPEKind(out peKind, out machine);

Console.WriteLine(peKind);

The results of peKind can be interpreted with:

Any CPU ILOnly
x86 ILOnly, Required32Bit
x64 ILOnly, PE32Plus

MITM using Chromium Embedded Framework and Fiddler

October 4, 2016 Leave a comment

For some background, I use a popular website that shows certain artifacts around my city. When a location is clicked, it’ll show what artifacts are available at that location. The website works by sending an AJAX request to an API when a location is clicked and returns a JSON serialized list of artifacts.

A few weeks ago, I wrote a script to call their API directly. The script contained an infinite loop to call their API every minute and notify me when it found new artifacts. I could run this script when I was sleeping or away from my computer and it would text me the details using Twilio when it found something.

However, the website started cracking down on unsolicited API calls to their service a few days ago. Their first attempt was to generate a unique token each time a user visits their website and that token was included as part of the API call. This was simple to bypass since my script could simply scrap the website for the token.

They wised up pretty quickly. A few days later, they started obfuscating how the token was generated and each API call required a new token. I spent an hour trying to deobfuscate how they generated the token, but I couldn’t figure it out without spending a large amount of time on it.

Fortunately, there’s still a way around it. Chromium Embedded Framework (CEF) allows me to embed a headless browser into my script that is able to execute JavaScript and everything else a normal user would be able to do.

I can load the website using CEF and inject JavaScript into the website to click on links.

var browser = new ChromiumWebBrowser("https://example.com");

while (!browser.IsBrowserInitialized)
{
	Console.WriteLine("Waiting for browser initialization...");
	Thread.Sleep(TimeSpan.FromSeconds(2));
}

while (browser.IsLoading)
{
	Console.WriteLine("Waiting for website to load...");
	Thread.Sleep(TimeSpan.FromSeconds(2));
}

Console.WriteLine("Finished browser initialization.");
			
await browser.EvaluateScriptAsync("$('#location').trigger('click'););

Triggering a click event will cause the website to generate a new token and submit an AJAX request to their API. Unfortunately, I couldn’t find any CEF documentation that showed me how to intercept the AJAX response.

Instead of trying to intercept the AJAX response using CEF, I used FiddlerCore to capture the AJAX response. FiddleCore can see all the traffic between CEF and their API.

FiddlerApplication.Startup(443, FiddlerCoreStartupFlags.Default);

FiddlerApplication.BeforeResponse += session =>
{
	if (session.RequestMethod == "CONNECT" || !session.LocalProcess.StartsWith("myApplication"))
		return;
	
	if (!session.HostnameIs("api.example.com"))
		return;
		
	dynamic result = JObject.Parse(session.GetResponseBodyAsString());
	
	// Do something with result
}

Instead of calling their API directly, I had to jump through a few hoops to get the data I wanted. Injecting click events into the website through CEF allowed me to automate the API calls without having to decipher the token generation. FiddleCore allowed me to monitor the traffic between CEF and their API.

Back from NSBCon 2015

December 10, 2015 Leave a comment

I just returned from Dallas having attended NSBCon 2015.  Overall, a very positive experience with several informative sessions.  It was a good opportunity for me to relax and rejuvenated since I haven’t been feeling very motivated lately.

One of the announcements was ServiceMatrix is being discontinued. I’ve never been a fan of using drag-drop tools for anything outside of user interface development, so the discontinuation will probably save me some stress in the future.

The next release of NServiceBus will utilize asynchronous message handlers, which is unfortunately a breaking change. The session continued with explanations on how to migrate existing codebases and pitfalls to watch out for.

The session on Akka.NET and the actor model peaked my interest. I’ve heard of Akka.NET, but I haven’t investigated any further. Having one of the developers talk about Akka.NET was a good chance to hear what it brings to table. Definitely something I’ll need to look into more.

I especially enjoyed listening to the panel discussions and hearing everyone’s opinion on topics that the audience brought up. It’s always a pleasure to listen to several well known developers in the industry talking about past, present, and future architectures/patterns being used in the wild. The topic around technological fads resonated with me. In my opinion, there are simply too many people that immediately become overzealous about new and shiny patterns or technologies without looking at past mistakes. History repeats itself and too many people ignore that.

There was another great session about things not to do with NServiceBus. While the examples were targeted to NServiceBus, the principle applies to a lot of other things. Too many times, certain software is shoved down everyone’s throat as the end-all solution for everything.

Everything considered, I enjoyed the four days I spent in Dallas. Most of the sessions were very informative and insightful, so I have plenty to think about.

Logging database and web service calls with PostSharp

November 4, 2015 Leave a comment

We’ve been having some sporadic performance problems with our website. We needed to find out which page or operation was taking too long to complete and exhausting all the worker threads. Unfortunately, due to the size of the codebase and the lack of performance auditing, it was difficult to pinpoint where the problem was occurring.

Only a small portion of the codebase was utilizing dependency injection, so we couldn’t decorate or intercept all dependencies with an auditing class. Fortunately, an IL weaving framework such as PostSharp can help with this situation. This was my first time using PostSharp, but I found it tremendously helpful.

A good would start would be logging database and web service calls.

using (SqlConnection conn = new SqlConnection("Server=.\\SQL2008; Database=Test; Trusted_Connection=True"))
using (SqlCommand cmd = new SqlCommand("cp_GetUserInfo", conn))
{
	cmd.CommandType = CommandType.StoredProcedure;
	cmd.Parameters.AddWithValue("@UserName", "JD");
	conn.Open();

	using (SqlDataReader reader = cmd.ExecuteReader())
	{
		while (reader.Read())
		{
			Console.WriteLine("User {0} {1}'s member ID is {2}.", reader["FirstName"], reader["LastName"], reader["MemberID"]);
		}
	}
}

Without modifying the existing code, I want to log the connection string, any parameters, and the amount of time it took to execute this stored procedure. We’ll inherit from OnMethodBoundaryAspect to record information before and after our database call.

[AttributeUsage(AttributeTargets.Assembly)]
[MulticastAttributeUsage(MulticastTargets.Method)]
[Serializable]
public class DatabaseAspect : OnMethodBoundaryAspect
{
	public override void OnEntry(MethodExecutionArgs args)
	{
		args.MethodExecutionTag = Stopwatch.StartNew();
		
		SqlCommand cmd = (SqlCommand) args.Instance;

		Console.WriteLine("Executing command: {0}", cmd.CommandText);
		Console.WriteLine("\t- Connection String: {0}", cmd.Connection.ConnectionString);
		
		List<string> parameters = new List<string>();

		for (int i = 0; i < cmd.Parameters.Count; i++)
			parameters.Add("\t- Parameter " + cmd.Parameters[i].ParameterName + ": " + cmd.Parameters[i].Value);

		if (parameters.Count > 0)
			Console.WriteLine(String.Join("\n", parameters));
	}

	public override void OnExit(MethodExecutionArgs args)
	{
		Stopwatch sw = (Stopwatch) args.MethodExecutionTag;
		sw.Stop();

		SqlCommand cmd = (SqlCommand) args.Instance;

		Console.WriteLine("Command \"{0}\" took {1} ms.", cmd.CommandText, sw.ElapsedMilliseconds);
	}
}

Running the code will produce the following:

Executing command: cp_GetUserInfo
        - Connection String: Server=.\SQL2008; Database=Test; Trusted_Connection=True
        - Parameter @UserName: JD
Command "cp_GetUserInfo" took 1124 ms.
User John Doe's member ID is 1234.

Great, now I can see the length of each database call and the parameters without digging through IIS logs hoping to find something to reconstruct the request. In additional to database calls, I want to log any web service requests. As with the database aspect, we can inherit from OnMethodBoundaryAspect to log information before and after the request.

[AttributeUsage(AttributeTargets.Assembly)]
[MulticastAttributeUsage(MulticastTargets.Method)]
[Serializable]
public class WebServiceAspect : OnMethodBoundaryAspect
{
	public override void OnEntry(MethodExecutionArgs args)
	{
		args.MethodExecutionTag = Stopwatch.StartNew();
		dynamic client = args.Instance;
		Console.WriteLine("Found service call to: {0}", client.Client.Endpoint.Address);
	}

	public override void OnExit(MethodExecutionArgs args)
	{
		Stopwatch sw = (Stopwatch) args.MethodExecutionTag;
		sw.Stop();

		dynamic client = args.Instance;
		Console.WriteLine("Service call to \"{0}\" took {1} ms.", client.Client.Endpoint.Address, sw.ElapsedMilliseconds);
	}
}

We’ll apply these aspects to the entire assembly using assembly attributes.

[assembly: WebServiceAspect(AttributeTargetMembers = "regex:Return|Use", AttributeTargetAssemblies = "Example", AttributeTargetTypes = "Example.WcfClient*")]
[assembly: DatabaseAspect(AttributeTargetMembers = "Execute*", AttributeTargetAssemblies = "System.Data", AttributeTargetTypes = "System.Data.SqlClient.SqlCommand")]

Muting sounds in a Chrome tab

May 1, 2015 Leave a comment

Although I still prefer the Firefox’s developer tools for debugging, I have switched to Chrome almost exclusively for my day-to-day browsing.

A while ago, Chrome added an audio icon to indicate which tabs were playing sounds.

Audio icon in Chrome

While I love this feature, I always wanted a way to manually mute a single tab. Well, there is a way and I can’t believe I never knew about it until now. Just copy and paste the following into Chrome’s address bar and enable the audio mute option:

chrome://flags/#enable-tab-audio-muting

Now I can click on the audio icon and mute a single tab without having to mute my entire computer.

Audio muted in Chrome

Encrypting files

October 16, 2014 Leave a comment

I have several files I need to backup to the cloud. I looked at automated backup solutions like Mozy, CrashPlan, etc…, but they were expensive compared to storage solutions like Amazon S3, Azure Storage, and others. So I figure that I can just encrypt the files myself and upload it to one of those services. I wrote the code below to encrypt my files:

void Main()
{
	string pass = "$ecret p@ssword";
	 
	string source = @"C:\file.dat";
	string encryptedDestination = @"C:\file.encrypted";
	string decryptedDestination = @"C:\file.decrypted.dat";
	
	byte[] salt = EncryptFile(pass, source, encryptedDestination);
	DecryptFile(pass, salt, encryptedDestination, decryptedDestination);
			 
	Console.WriteLine ("Done");
}

byte[] EncryptFile(string password, string source, string destination)
{	
	if (!File.Exists(source))
		throw new ArgumentException("Source does not exist.", "source");
	
	if (File.Exists(destination))
		throw new ArgumentException("Destination already exist.", "destination");
		
	byte[] IV;
	
	using (var provider = new RijndaelManaged())
	using (var passwordGen = new Rfc2898DeriveBytes(password, provider.IV))
	{
		provider.Key = passwordGen.GetBytes(provider.KeySize / 8);
		IV = provider.IV;
			
		using (var encrypt = provider.CreateEncryptor())
		using (var destinationStream = File.Create(destination))
		using (var cryptoStream = new CryptoStream(destinationStream, encrypt, CryptoStreamMode.Write))
		using (var sourceStream = new FileStream(source, FileMode.Open, FileAccess.Read, FileShare.Read))
		{
			sourceStream.CopyTo(cryptoStream);
		}
	}
	
	return IV;
}

void DecryptFile(string password, byte[] salt, string source, string destination)
{
	if (!File.Exists(source))
		throw new ArgumentException("Source does not exist.", "source");
	
	if (File.Exists(destination))
		throw new ArgumentException("Destination already exist.", "destination");
		
	using (var provider = new RijndaelManaged())
	using (var passwordGen = new Rfc2898DeriveBytes(password, salt))
	{
		provider.Key = passwordGen.GetBytes(provider.KeySize / 8);
		provider.IV = salt;
				
		using (var decrypt = provider.CreateDecryptor())
		using (var destinationStream = File.Create(destination))
		using (var cryptoStream = new CryptoStream(destinationStream, decrypt, CryptoStreamMode.Write))
		using (var sourceStream = new FileStream(source, FileMode.Open, FileAccess.Read, FileShare.Read))
		{
			sourceStream.CopyTo(cryptoStream);
		}
	}
}

Although the encryption code works, I still need to store the generated initialization vectors (IV) somewhere along with the encrypted files. That’s kind of a hassle. Instead, I can prepend the IV to the encrypted files. When I’m decrypting files, I can read the first 16 bytes and assume that’s the IV.

void EncryptFile(string password, string source, string destination)
{   
    if (!File.Exists(source))
        throw new ArgumentException("Source does not exist.", "source");
     
    if (File.Exists(destination))
        throw new ArgumentException("Destination already exist.", "destination");
     
    using (var provider = new RijndaelManaged())
    using (var passwordGen = new Rfc2898DeriveBytes(password, provider.IV))
    {
        provider.Key = passwordGen.GetBytes(provider.KeySize / 8);
                     
        using (var encrypt = provider.CreateEncryptor())
        using (var destinationStream = File.Create(destination))
		using (var cryptoStream = new CryptoStream(destinationStream, encrypt, CryptoStreamMode.Write))
		using (var sourceStream = new FileStream(source, FileMode.Open, FileAccess.Read, FileShare.Read))
		{
			destinationStream.Write(provider.IV, 0, provider.IV.Length);
			sourceStream.CopyTo(cryptoStream);
		}
    }
}
 
void DecryptFile(string password, string source, string destination)
{
    if (!File.Exists(source))
        throw new ArgumentException("Source does not exist.", "source");
     
    if (File.Exists(destination))
        throw new ArgumentException("Destination already exist.", "destination");
	
	byte[] salt = new byte[16];
	
	using (var sourceStream = new FileStream(source, FileMode.Open, FileAccess.Read, FileShare.Read))
	{
		sourceStream.Read(salt, 0, salt.Length);
	}
	
    using (var provider = new RijndaelManaged())
    using (var passwordGen = new Rfc2898DeriveBytes(password, salt))
    {
        provider.Key = passwordGen.GetBytes(provider.KeySize / 8);
        provider.IV = salt;
                 
        using (var decrypt = provider.CreateDecryptor())
        using (var destinationStream = File.Create(destination))
        using (var cryptoStream = new CryptoStream(destinationStream, decrypt, CryptoStreamMode.Write))
        using (var sourceStream = new FileStream(source, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
			sourceStream.Seek(salt.Length, SeekOrigin.Begin);
            sourceStream.CopyTo(cryptoStream);
        }
    }
}

Extracting text messages on iPhone

August 20, 2014 1 comment

I bought an iPhone a few years ago and I’m about to switch phones. I didn’t want to lose the history of my text messages, so I wanted a copy of all my text messages.

After manually backing up the phone using iTunes, we can navigate to where the backup is stored locally. In my case, the backup is stored at:

C:\Users\<MyUserName>\AppData\Roaming\Apple Computer\MobileSync\Backup\

All text messages are stored in a SQLite file named 3d0d7e5fb2ce288813306e4d4636395e047a3d28. There are two tables I’m going to focus on: message and handle. The message table contains your entire history of text messages and various flags to determine whether a message was sent or received, whether the message was read, etc…. The handle table contains a list of phone numbers you’ve messaged and some additional information such as whether they were sent as a text message (SMS) or an iMessage.

Since I just wanted to backup my entire history, I can join these two tables using the following query:

select 
	DATETIME(date + 978307200, "unixepoch", "localtime") as "Date", 
	h.id as "Phone Number", 
	m.text as "Text"
from message m inner join handle h on m.handle_id = h.rowid
order by m.rowid desc

I did have some trouble with the date column in the message table. The date column stores a number like 340475640, which I wrongly assumed was the Epoch time that began on January 1, 1970. Turns out that dates in iOS starts on January 1, 2001. The magic number 978307200 in the query above represents how many seconds there are between these two dates.

Because LINQPad has support for SQLite using the IQ driver, it was easy to use LINQpad to query this database using both SQL and LINQ.

(from m in message
join h in handle
on m.handle_id equals h.ROWID
orderby m.date descending
select new 
{
	Date = new DateTime(2001, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
		.AddSeconds(m.date.Value)
		.ToLocalTime(),
	PhoneNumber = h.id,
	Text = m.text
})
.Dump();