Wednesday, March 11, 2009

Reading and Writing to Another Process

I had a conversation with a friend the other day about this topic, he wasn't aware that this was indeed possible on OSX. As a side note, if your operating system supports debugging, and more specifically, attaching and detaching a debugger to an already running process then the operating system has to have some support for this. Just as a reference, here's a rundown of the functions you can use to read or write bytes to other processes on Linux, Windows and Mac OS X.

On Linux, you need to look no further than open(), read(), write() and close(). You just find the PID you are looking for under the special "/proc" file system, in there, change to the directory that corresponds to your PID. Inside, there is a file named "mem". If you have access, you can just open this file and read and write to it.

On Windows, given a PID, get a process handle using the OpenProcess() function. From there, you can reserve space in the other process by using VirtualAllocEx(). You can use WriteProcessMemory() and ReadProcessMemory() to write and read to this other process.

On Mac OS X, you first obtain a Mach task using task_for_pid(), once you have that, you only need to use vm_read() and vm_write() to read and write to the other process.

All of the above assume that the operating system is clamping your access to other processes based on your credentials otherwise you get something like this.

Tuesday, March 10, 2009

Secure IPC in OS X - Part 1

This is the first in a series of posts about a specific implementation of a secure IPC solution for OS X.

First, what do I mean by secure IPC? IPC is the communication between two or more processes on a single computer. There are many methods for doing IPC, some are applicable to most operating systems and others can be quite specific. On OS X, the most obvious choices for IPC are:
In each of these cases, lets assume there is a server process running with elevated privileges that handles requests from one or more client processes. In a typical IPC setup, the server waits for instructions from the client to perform a task. None of the three methods have the ability to establish the sender's identity "built-in." Thus, a malicious process could communicate with the server and get it to do undesirable things. Identifying the sender will be covered later in the series.

You might be thinking there are well-documented industry standard ways to secure client-server communication, in use in important applications like online banking. These methods employ public-key cryptography to ensure the privacy of the communication as well as the identities of the communicating parties. This hinges upon a malicious user not having access to the private key, in other words it is security based on what-you-know. On a single computer, what-you-know security fails because the programmer has to assume that no secrets will remain secret for very long if they are installed on a user's machine (for instance, an embedded private key can be extracted from the binary). The alternative is security based on who-you-are.

For my purposes, the data being transferred between the processes did not need to be encrypted, only the identity of the communicating parties needed to be confirmed. Both OS X and Windows have the ability to establish the identity of an application using code-signing. Thus, the goal of secure IPC, for my purposes, can be thought of as, retrieving and validating the code-signature of the processes participating in IPC.

Part 2 will deal with determining the identity of these processes at run time.

Using code-signing in OS X - 10.6 update

I wrote a few days ago about the private code-signing API in OS X, and expressed some doubt as to whether applications using it will get burned when 10.6 is released.

There is some good news. I have tried the latest developer seed build, 10A286, and the codesign tool, and my code, works!

Thursday, March 5, 2009

theothermike.printf("hello\n") && lessons(XmlSerializer)

This is my first article here, so I figure I'd do a little introduction first. I'm a professional software developer/geek, with expertise mainly in Perl and *nix environments. I've been toying around with Java and C# in the last couple of years, and more recently, I've started using C#/.NET at my day-job in a specific project.... which brings me to my first post.

While working on making a SOAP request and using the XML serialization facilities in .NET, I spent the better part of a day tracking down why all of a sudden my code had started throwing runtime exceptions when changing a class member from being an ArrayList to a generic List<SomeClass>

Thinking at first that the serialization services didn't actually work with generic collections, I had found several examples that proved otherwise..

Now keep in mind that I'm fairly new to Visual Studio (this project is in 2005), and IDEs in general as I had mainly been using Emacs in a terminal window before. So, when I was presented with the exception dialog, I was extremely annoyed at how many 'levels' I had to dig into the dialog to actually get to the exception information I needed. For some reason, it doesn't word wrap either, and even stretching the dialog across my 2 monitor setup doesn't reveal everything in the exception.

Almost ready to give up using generic collections, I started modifying the code to use ArrayList and arrays[], but cleaner than it had been before.

Now for some reason, the GUI was STILL throwing an exception... but at least it 'bubbled' up to a different exception dialog that would actually let me see the text of the entire exception*.

Way down in the stack, I saw the error message causing my problems wasn't related to the fact that I was using generic collections, but rather due to the fact that the class used in the generic collection (ie. SomeClass) didn't have a default constructor anymore since I had created another constructor to take parameters for convenience. This does make perfect sense after I realized my mistake, but it didn't even occur to me as I'm still fairly new to C# (I had assumed the default constructor would still be there even though I didn't define it)

Adding a default constructor of course took care of the problem, and I reverted back to using List instead of ArrayList.

Applying some tips from pjulien, I also made the class 'sealed' and exposed the List using IList instead ..... much nicer:)

... live and learn

* of course you can see the entire exception in the 'output' window of VS, but this I learned after the fact

Using code-signing in OS X

OS X 10.5 includes code-signing support. Unlike Windows, code-signing in 10.5 doesn't really affect the user experience, but that will almost certainly change in future versions. The only code-signing aware features in OS X are the firewall and parental control systems. Both of these systems use the code-signature to identify an application independently of its location on disk and of its version, therefore, firewall preferences can be saved accross upgrades.

OS X 10.5 allows you to sign your applications and verify their on disk and runtime signatures. Here's the catch; Apple only support doing this via the codesign utility.

But what if I want to make use of code-signing in my application, for instance, checking the validity of a process I'm about to do IPC with? If you are like me, you don't like the idea of executing codesign directly and picking up the return code, you'd prefer an API. Well one exists and its really nice. Here is the code to verify the runtime signature of a process:

SecCodeRef code = 0;
SecCodeCreateWithPID(pid, kSecCSDefaultFlags, &code);
SecCodeCheckValidity(code, kSecCSDefaultFlags, 0);

Obviously, you'll have to check return codes and such, but 3 lines for code-signature validation is pretty nice. But all it checks is that the code hasn't been tampered with, no identity checks here. Adding your own extra requirements (like an identity check) is also easy (see man csreq for details on requirement strings):

SecRequirementRef requirement = 0;
SecCodeRef code = 0;
SecRequirementCreateWithString("certificate root H=\"abcdef12345\"", kSecCSDefaultFlags, &requirement);
SecCodeCreateWithPID(pid, kSecCSDefaultFlags, &code);
SecCodeCheckValidity(code, kSecCSDefaultFlags, requirement);


For brevity, I lied about being able to pass a char* to create the requirement (it should be a CFString) and I didn't check my return codes. Replace "abcdef12345" with your public key's SHA1 and you can verify that the code is signed by you. Pretty nice. Much better than the 100 or so lines of CryptUI code I had to write to do the same thing. As always though, there is a downside, the API is private, and codesign doesn't work on the preview builds of Snow Leopard, which makes me think they may have changed the something. Bummer.

Still, if you're interested download libsecurity_codesigning from the Darwin source code page and enjoy.

New Contributor

I'm going to starting contributing to this blog. I will mostly post about things I find interesting as I learn my way around OS X and Objective-C, from the perspective of a person coming from Windows/Linux and C++.

By way of introduction, a bug report. NSFileManager reads past the end of allocated memory. The details can be found at rdar://6636446, Apple have fixed the issue for some future release (10.5.7 or 10.6?).

I came across this by running my application with Guard Malloc. For the Linux developer, Guard Malloc is basically DUMA for Mac. Like Linux, it is easily used via the Mac (pseudo-)equivalent of LD_PRELOAD, DYLD_INSERT_LIBRARIES, or if you can stand using XCode long enough, it can be enabled at the bottom of the "Build" menu.

Wednesday, March 4, 2009

Windows 7 Shadow Copies

Since Windows Server 2003, Windows has had a feature called shadow copies. Basically, this allows you to get back to previous versions of existing or deleted files. The feature was later enhanced in Vista to make the "system restore" feature. Namely, the system takes snapshots of important system files your computer needs to boot by creating "restore points". At any point in the future you can revert to such a restore point. This can be because your system stop rebooting or you just noticed that game demo included SecuROM and is still installed even if the game demo no longer is.


The feature works has advertised however, there was no way in Vista to know how much disk space this feature was using or could use. Windows 7 includes new configuration options that control these settings.

shadow1shadow2

JavaFX

Now that the 1.0 release has been superseded by the 1.1 release, I decided it was time to look at JavaFX and see if there was anything there.

The first thing that hits you when looking at the samples is how smooth everything is on screen. That's good because Sun really needs to impress with these samples if it has any hope of getting developers to use them.

The second thing that hits you is the claim about there is no JavaFX mobile, there is only JavaFX. Code you write in JavaFX will work over "all the screens of your life". It's certainly possible to write a JavaFX application that would work over a phone, BD player, TV, browser and your desktop. Unfortunately, you wouldn't want too, the effort required to get that going wouldn't be worth it. The problem doesn't arise when you look at what's there but what isn't. Most basic controls like a text box or a list are imported from Swing verbatim or are simply missing. In other words, you have to use Java/Swing to add the missing functionality in your own application.

Now, if you're planning on deploying to all of the above platforms. All these Java stacks have swing with the exception of Java ME/CLDC. The CLDC environment happens to be the one that sits on those 2 billion phones that Sun keeps talking about and that's an issue. It's possible but highly unlikely that your application will not require any user interaction beyond flashy effects. The real problem with the CLDC however, is that it doesn't have AWT either. So beyond writing a complete replacement for these controls in CLDC, which is what the LWUIT project is doing, there isn't much you can do here. Is it possible that Sun will finally start to push Java ME/CDC for smart phones? I don't know, time will tell. However, the BlackBerry is still the most popular business oriented smart phone out there and it's based on CDLC. I say "based", because that virtual machine has some serious issues that I feel invalidates it as a Java virtual machine in the first place. Meaning getting JavaFX to run on a BlackBerry is still a big question mark.

The other big news is that Sun has reported they now have done 100 million installs of JavaFX on the desktop. I was really impressed by this at first because I thought this was people going to javafx.com, downloading the bits and installing them. What else could it be right? There wasn't a new Java 6 update so they couldn't have been piggy backing on the regular Java runtime from Sun to deploy JavaFX right? Wrong. Java 6 update 12 is still the latest release, but if you go to java.com right now and inspect the current installer, you can see that the installer binary has been modified to include JavaFX. 100 million desktop installs is still very impressive, Silverlight just recently passed this milestone and it has been out for far longer. However, let's face it, JavaFX is getting deployed because of Java Update, not because end users are excited about it and getting the bits themselves.

JavaFX on the desktop is still interesting. Thanks to the massive work that was done in Java 6 update 10, it can leverage the completely overhauled applets and web start systems in that release. Which means you can deploy your FX code as applets or web start applications or a combination of both. For example, most of the samples on javafx.com run in the browser, however installing on the desktop just requires the user to press "Alt" and drag the applet outside the browser to have the application live on your desktop. What's also good about this process is that the install is per user, so there are no UAC escalation prompts so anyone can install these applications that they be an administrator or not.

More good stuff:
  • Sun decided that it wasn't going to re-invent a completely new set of tools for content designers. Instead, it wrote plugins for Adobe's creative suite.
  • Media codecs. Finally, video comes to the Java platform. JMF (Java Media Framework) is dead and buried, it was last updated in 2003. JavaFX features On2 codecs and plugs into DirectShow on Windows and QuickTime on OSX.
  • JavaFX isn't a virtual machine, it runs on top of an existing JVM. That's good news indeed because in conjunction with Java Web Start, if your application is started by someone that still doesn't have JavaFX, just Java, the application will still load just fine. The JavaFX jar is just another jar which means web start will just grab it just like any other jar that is part of your application. Furthermore, if your users don't have Java, you can still use Sun's JavaScript script for Java deployment to get it to end users.
  • Updatable runtime even for phones. This is a departure from how Sun has been doing business on phones. Having the runtime updatable over the air is a really a good thing. Even if you bought a first generation iPhone, you haven't been left out in the cold, your system has been upgradable to every release that has been put out there. Sure, it's not over the air, you need a computer to install it but this is still a good thing.
Now some bad stuff:
  • Applets still take too long to start. Java 6 update 10 really helps but it still isn't good enough. It needs to be instantaneous if Sun has any hopes of replacing Flash with this technology. When you get to a web page, your banner ads have to be showing immediately, they can't be showing the Java spinning logo.
  • The Java system tray icon and bubble advertisement. Are you kidding me here? Really, really annoying.
  • No Android support outside the traditional model. That means Android handset developers need to license it from Sun and it doesn't come over the air. It follows the traditional model of what ships with the phone, dies with the phone. Of course, Android unfortunately hasn't exactly caught on fire, might be a non-issue here.
  • Not all JavaFX versions have been released. Namely Linux.
  • No visual editor. I've said many times over now that NetBeans' excellent matisse editor needs to move to the next level, beyond just Swing/AWT support. Please note that visual editors are available from 3rd parties.
All in all, I hope Sun keeps working really hard on this. The 1.1 release came mere months after the 1.0 release and I think it needs to keep doing that. Release very often so that it can patch holes and missing functionality bit by bit, forget the huge releases here, if it does that, it will be in a position where JavaFX 1.1 is competing against Silverlight 3. JavaFX's scope, i.e., the total number of classes, already doesn't compare favorably to Flex or Silverlight, let it gain ground bit by bit instead of waiting till the platform is abandoned before making another release.

Next up, Silverlight...

Windows 7 DST Heads Up isn't New

Turns out this feature is in Vista also.