Index: src/wp-admin/js/theme.js
===================================================================
--- src/wp-admin/js/theme.js	(revision 27116)
+++ src/wp-admin/js/theme.js	(working copy)
@@ -694,13 +694,18 @@
 // Listens to [theme] and [search] params
 themes.routes = Backbone.Router.extend({
 
-	initialize: function() {
-		this.routes = _.object([
-		]);
+	routes: {
+		'themes.php?theme=:slug': 'theme',
+		'themes.php?search=:query': 'search',
+		'themes.php?s=:query': 'search'
 	},
 
 	baseUrl: function( url ) {
-		return themes.data.settings.root + url;
+		return 'themes.php' + url;
+	},
+
+	search: function( query ) {
+		$( '.theme-search' ).val( query );
 	}
 });
 
@@ -720,32 +725,39 @@
 	},
 
 	render: function() {
+		var root;
+
 		// Render results
 		this.view.render();
 		this.routes();
 
-		// Set the initial theme
-		if ( 'undefined' !== typeof themes.data.settings.theme && '' !== themes.data.settings.theme ){
-			this.view.view.theme.trigger( 'theme:expand', this.view.collection.findWhere( { id: themes.data.settings.theme } ) );
+		// Sets up Backbone.history
+		// Only change root if we have a pushState enabled browser -
+		// fixes redirect to /wp-admin/#themes.php bug in IE8
+		if ( window.history && window.history.pushState ) {
+			root = themes.data.settings.root.replace( 'themes.php', '' );
+		} else {
+			root = themes.data.settings.root;
 		}
 
-		// Set the initial search
-		if ( 'undefined' !== typeof themes.data.settings.search && '' !== themes.data.settings.search ){
-			$( '.theme-search' ).val( themes.data.settings.search );
-			this.themes.doSearch( themes.data.settings.search );
-		}
-
-		// Start the router if browser supports History API
-		if ( window.history && window.history.pushState ) {
-			// Calls the routes functionality
-			Backbone.history.start({ pushState: true, silent: true });
-		}
+		Backbone.history.start({ root: root, pushState: true, queryUri: true });
 	},
 
 	routes: function() {
+		var self = this;
 		// Bind to our global thx object
 		// so that the object is available to sub-views
 		themes.router = new themes.routes();
+
+		// Handles theme details route event
+		themes.router.on( 'route:theme', function( slug ) {
+			self.view.view.expand( slug );
+		});
+
+		// Handles search route event
+		themes.router.on( 'route:search', function( query ) {
+			self.themes.doSearch( query );
+		});
 	}
 };
 
Index: src/wp-admin/themes.php
===================================================================
--- src/wp-admin/themes.php	(revision 27116)
+++ src/wp-admin/themes.php	(working copy)
@@ -100,9 +100,6 @@
 		'installURI'    => ( ! is_multisite() && current_user_can( 'install_themes' ) ) ? admin_url( 'theme-install.php' ) : null,
 		'confirmDelete' => __( "Are you sure you want to delete this theme?\n\nClick 'Cancel' to go back, 'OK' to confirm the delete." ),
 		'root'          => parse_url( admin_url( 'themes.php' ), PHP_URL_PATH ),
-		'theme'         => esc_html( $theme ),
-		'search'        => esc_html( $search ),
-
 	),
  	'l10n' => array(
  		'addNew' => __( 'Add New Theme' ),
Index: src/wp-includes/js/wp-backbone.js
===================================================================
--- src/wp-includes/js/wp-backbone.js	(revision 27116)
+++ src/wp-includes/js/wp-backbone.js	(working copy)
@@ -381,4 +381,55 @@
 
 		ready: function() {}
 	});
+
+	// Backbone.History.prototype
+	// --------------------------
+	//
+	// Extends Backbone.History to support urls with GET queries in WordPress
+	// Supports basic form ?param=value passing 'paramvalue' as the fragment
+	_.extend( Backbone.History.prototype, {
+
+		// Keep original fragment resolver available
+		originalFragment: Backbone.History.prototype.getFragment,
+
+		// ### Get the fragment
+		//
+		// If history constructor includes 'queryUri' param
+		// Use our own getFragment resolver to handle the location changes
+		//
+		// Appends 'location.search' to pathname in order to deal with
+		// query variables present in URI
+		//
+		// Returns fragment '?paramvalue'
+		getFragment: function( fragment, forcePushState ) {
+			var root;
+
+			// If queryUri is not set via Backbone.history.start
+			// return the original fragment handler
+			if ( ! Backbone.history.options.queryUri ) {
+				return this.originalFragment.apply( this, arguments );
+			}
+
+			// If we got this far, parse this.location.search
+			// since we have a URL with query vars
+			if ( fragment == null ) {
+				if ( this._hasPushState || ! this._wantsHashChange || forcePushState ) {
+
+					// Constructs fragment attaching the query parameters
+					fragment = this.location.pathname + this.location.search;
+					root = this.root.replace( /\/$/, '' );
+
+					if ( ! fragment.indexOf( root ) ) {
+						fragment = fragment.slice( root.length );
+					}
+
+				} else {
+					fragment = this.getHash();
+				}
+			}
+
+			return fragment.replace(/^\/+|\/+$/g, '');
+		}
+	});
+
 }(jQuery));
