ISS Maintenance Mode Easily With URL Rewrite

I needed to take down one of my sites a bit ago and was looking for a method to keep it up, just not to the outside world. Sadly, all the methods I found where based around using ASP.NET’s trick with the known app_offline.htm page. In my situation, this didn’t help since I’m not using any web app on my site.

The few rewrite rules I found were also a bit overkill and didn’t really fit my needs.
I didn’t want to make a custom page, didn’t want to make another website to fake the page, etc.
So tinkering with a custom rule condition I was able to get what I wanted done.

Here is how I can locally still access the website, while all remote requests are rejected:

In IIS Manager choose your desired site to put into maintenance mode.

  • Choose URL Rewrite from the modules list for the site. (Be sure to set this on the base dir of the site to block all requests for the entire site.)
  • Add a new rule by right-clicking on the inbound rules.
  • Choose ‘Request Blocking’ from the selection of choices.
  • On the rule properties popup, fill out as follows:
    • Block access based on: URL Path
    • Block request that: Matches the Pattern
    • Pattern (URL Path): *
    • Using: Wildcards
    • How to block: Send an HTTP 403 Response
  • Next, click ok to add the rule.
  • Double-click the newly added rule to open the Edit Inbound Rule panel for the specific rule.
  • Under conditions, click add.
  • Fill out the condition properties as follow:
    • Condition input: {REMOTE_HOST}
    • Check if input string: Does Not Match the Pattern
    • Pattern: ::1
    • Ignore case: true
  • Click ok and you’re all set.

The site should now be blocked from remote requests that are not from the remote host ‘::1’ which according to the logs is used when the local server attempts to request pages from itself.

Hope this helps someone else with a similar issue. 🙂

Visual Studio 2012 – Windows XP Targeting

Warning:

The information in this post is not recommended to be followed!
This is simply an observation I made a while ago when debugging a user problem for a project I work on called Ashita.

This issue is no longer a problem with Visual Studio 2012 Update 1!

The Problem

After upgrading Ashita to Visual Studio 2012, we had noticed that some users were complaining that our application no longer worked on their system. This resulted in me investigating and finding out the issue was only happening to users on Windows XP. I tossed Windows XP onto a virtual machine to replicate the issue and sure enough our app would not work on the VM.

Further investigation proved that Visual Studio 2012 (stock) did not support Windows XP machines. After many complaints to Microsoft from developers, though, Microsoft released Update 1 to VS2012 which included the toolset option to target Windows XP machines when compiling. (Read here: http://blogs.msdn.com/b/vcblog/archive/2012/10/08/10357555.aspx)

However at the time of this issue, we did not have access to Update 1 yet so finding a work-around was needed. Upon attempting to load our application, I would get the following error:
“Ashita Boot.exe is not a valid Win32 application.”

Knowing that the application works fine on all other versions of Windows after WinXP we knew this was a fluke of an error that had no real merit. I compared the files of a VS2010 compile and VS2012 compile and noticed, mainly, that in the file header there were two main things that peeked my interest:
– MajorOperatingSystemVersion
– MajorSubsystemVersion

While compiling in Visual Studio 2012, these are set to the value 0x06
While compiling in Visual Studio 2010, these are set to the value 0x04

So the first step was to set these to 0x04 in the newer binary. Afterward I was greeted with another error saying that an import was not found for ‘GetTickCount64’. Given that the Windows XP machine does not have this API, I had to also edit the import table to target ‘GetTickCount’ instead of the 64bit version.

Afterward this fixed our application and made it work for those users temporarily.

Tool I used to apply the file fixes: (CFF Explorer)
http://www.ntcore.com/exsuite.php

Ashita Launcher

About The Project

Since joining the Ashita project a while back, the loader/injector for the project was always a bit underwhelming. It was tossed together just to work with the basic injection method to focus time on the core hook of the project. Because of this I always had some ideas in mind of redoing it and bringing life to the loader as well as making it a central tool for configuring the profiles so non-computer literate users could make use of of the project with ease.

I started the Ashita Launcher as a side project that I worked on in my spare time while working on the core hook of the project too.

Ashita Launcher is coded in C# using WPF. It makes use of the following libraries:

  • GalaSoft MVVM Light (WPF4)
  • MahApps.Metro

Features

The Ashita Launcher has the basic needs of injecting the Ashita Core hook into the Final Fantasy XI process (pol.exe) but also extends into a full configuration editor as well as semi-automatic updater.

Users are greeted at launch with a list of currently found profiles in their Config\Boot folder:
laucher

Following this, users can select a configuration and edit it to allow for easy alterations:
editor

This project is open source and can be found here:
https://github.com/atom0s/AshitaLauncher

about

Native CLR Hosting (With separate AppDomains per-module.)

Notice: All error handling / checking has been stripped from the code to make things as basic and easy to understand. Majority of the calls made in the below code are to COM objects which use HRESULT returns. Always check your returns before continuing to help prevent crashes!

One of the biggest, I consider, issues with .NET and plugins is that you can’t truly unload a managed module without fully shutting down the application domain it is ran within. Things linger in memory and the garbage collection only does so much. In C/C++ the simple FreeLibrary handles this but we don’t have that luxury in C#. Instead, the easiest way to truly get unloading plugins is by loading each one into it’s own AppDomain.

Doing this with the use of ‘mixed’ code is simple and documented, however doing this in pure native C++ is not. It involves working with the COM interfaces of the CLR and such which does not have much documentation, and after a certain pointer, there is none. There also is a lack of examples showing how to do it online / open source. For someone like me, I personally enjoy both .NET (C#) and C/C++, however, I enjoy them being separate. I do not like VC++, the look and feel of the code is just wrong to me. I do not use it, and do not plan to use it. (This is my opinion, I’m sure yours will differ, that’s not the point of this post.)

Anyway, getting into the code. To start, this article will be based around how I implemented things, and what for. So a little back story. I work on a project that is an injected hook into a popular MMORPG. The purpose of this hook is to extend the ability of the game to make it better enjoyable to play. The focus is not cheating related, but the project does not limit what the users can do with the plugin interface that is exposed. The project is fully coded in C++ and the extension SDK exposes a collection of interfaces that the users can use to interact with the core hook. This is done by the hook loading plugins and passing a core object pointer to them which is casted to the core interface object.

With this I created an extension for our hook called ‘Bootstrap’. The purpose of this extension is to load the CLR into the process as well as creating new appdomains for each C# extension that it loads. I wanted to ensure that these plugins can be fully unloaded during runtime because being an MMO, the game does take up it’s own amount of resources and such. Keeping things clean and limited help out a lot.

So we have:

Hook <- -> Bootstrap Extension <- -> Managed Extension(s)

When Bootstrap first starts, we want to ensure we load the CLR runtime first and immediately.
I do that with the following little bit of code:

// Bind to the given runtime..
ICorRuntimeHost* lpRuntimeHost = NULL;
CorBindToRuntimeEx( L"v4.0.30319", L"wks", 0, CLSID_CorRuntimeHost, IID_PPV_ARGS( &lpRuntimeHost ) );

// Attempt to start the runtime..
lpRuntimeHost->Start();

Next, when a managed plugin is requested to start, Bootstrap will do some minor checking to ensure the file exists and such. Once it ensures the plugins not already loaded and it exists on disk, it will attempt to load it.

The next step is to load this plugin into its own AppDomain. For starters, I wrote a simple wrapper to hold the important interfaces that this plugin created when being loaded like this:

struct managedplugin_t
{
    std::wstring                m_PluginName;
    std::wstring                m_PluginPath;

    CComPtr<IUnknown>           m_AppDomainSetupUnknown;
    CComQIPtr<IAppDomainSetup>  m_AppDomainSetup;

    CComPtr<IUnknown>           m_AppDomainUnknown;
    CComPtr<_AppDomain>         m_AppDomain;

    CComPtr<_Assembly>          m_AppAssembly;
    CComVariant                 m_AppVariant;
    
    CComPtr<IAshitaExtension>   m_AppInstance;

    bool                        m_IsDirect3DReady;

    managedplugin_t()
    {
        this->m_PluginName              = L"";
        this->m_PluginPath              = L"";
        this->m_AppDomainSetupUnknown   = NULL;
        this->m_AppDomainUnknown        = NULL;
        this->m_AppDomain               = NULL;
        this->m_AppAssembly             = NULL;
        this->m_AppVariant              = NULL;
        this->m_AppInstance             = NULL;
        this->m_IsDirect3DReady         = false;
    }
};

Next, the first step is to create a new AppDomain. We want to create a DomainSetup object first to set some properties for the domain, such as where it will resolve its assemblies from and such. Afterward we create the domain with this new setup information:

// Create a new AppDomain setup object for the new domain..
this->m_RuntimeHost->CreateDomainSetup( &plugin->m_AppDomainSetupUnknown );

// Fill some basic structure info about this domain..
plugin->m_AppDomainSetup = plugin->m_AppDomainSetupUnknown;
plugin->m_AppDomainSetup->put_ApplicationBase( CComBSTR( this->m_PluginBasePath.c_str() ) );
plugin->m_AppDomainSetup->put_ShadowCopyFiles( CComBSTR( "true" ) );
plugin->m_AppDomainSetup->put_ApplicationName( CComBSTR( pluginName.c_str() ) );

// Create the new AppDomain..
this->m_RuntimeHost->CreateDomainEx( pluginName.c_str(), plugin->m_AppDomainSetupUnknown, NULL, &plugin->m_AppDomainUnknown );

// Obtain the actual AppDomain object..
plugin->m_AppDomainUnknown->QueryInterface( __uuidof( mscorlib::_AppDomain ), (void**)&plugin->m_AppDomain );

Now we want to load the plugin file into this AppDomain. My method was to have users create their plugins a specific way. Each plugin is loaded by its name, and then it must use a public class named ‘Main’ that inherits my C# implementation of our IAshitaExtension base class. This way I can forward all the C++ plugin calls to the C# plugins. So we load the plugin now like this:

// Load the plugin module into the AppDomain..
plugin->m_AppDomain->Load_2( CComBSTR( mainInterface.c_str() ), &plugin->m_AppAssembly );

// Create instaoce of the 'Main' class object..
plugin->m_AppAssembly->CreateInstance_2( CComBSTR( mainInterface.append( L".Main" ).c_str() ), true, &plugin->m_AppVariant );

// Obtain instance of our base class from this newly created instance..
plugin->m_AppVariant.punkVal->QueryInterface( __uuidof( IAshitaExtension ), (void**)&plugin->m_AppInstance );

One major thing to note here. For some reason CreateInstance_2 does not return properly. If it fails to create an instance of the given object, it will still return S_OK. You need to check the VARIANT object it returns and ensure it is valid. You can do this by checking it like:

if (plugin->m_AppVariant.vt == VT_EMPTY || plugin->m_AppVariant.vt == VT_ERROR)
{
    /** Object is invalid.. **/
}

Next is understanding the relationship between C++ and C# in our extensions. As I said above, the C# extensions inherit a managed base class, which looks like this:

namespace ManagedExample
{
    public class Main : AshitaBase
    {
        public override bool Load(IntPtr ashitaCore)
        {
        }
    }
}

The way this works is that AshitaBase is actually an abstract class.
This class inherits a base COM exposed interface, which in turn these look like this:

[ComVisible(true)]
[Guid("7805E68A-A028-433C-BB73-38D34D7208C5")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAshitaExtension
{
    [ComVisible(true)]
    [return: MarshalAs(UnmanagedType.I1)]
    bool Load(IntPtr ashitaCore);
}

public abstract class AshitaBase : IAshitaExtension
{
        public virtual bool Load(IntPtr ashitaCore)
        {
            return false;
        }
}

I had to use a COM exposed interface like this in order to be able to call things easily on the C++ side. With it setup like this, and with the above C++ code, we can now tell the C# plugin we loaded to call it’s Load function like this:

bool bReturn = false;
plugin->m_AppInstance->Load( (long)this->m_AshitaCore, (unsigned char*)&bReturn );

And there we have it, CLR hosting in pure native C++ 🙂

There are some things with this that I am still trying to figure out, such as adding an UnhandledException handler to each AppDomain but I am unsure how to properly call the m_AppDomain->add_UnhandledException function at this time.

Feel free to leave comments, suggestions, etc. Hope this helps someone in the future.

Some minor things I forgot to mention, here are the includes and other definitions needed for this stuff:

#pragma comment( lib, "mscoree.lib" )
#include <mscoree.h>

#include <atlbase.h>
#include <atlsafe.h>
#include <metahost.h>

#import "mscorlib.tlb" raw_interfaces_only

// Import of my managed base class information..
#import "../../build/Extensions/Managed/AshitaAPI.tlb" no_namespace named_guids raw_interfaces_only

.NET Header Reader

Wrote this for someone on Tuts4You the other day to show how to read the flags field from the IMAGE_COR20_HEADER section of a PE file header. It’s fairly plain and has little error checking. If it throws an exception it will crash since it was just a basic ‘how-to’ type thing.

Credits are in the HeaderHelper.cs class since that contains the main jist of things.

Download:
DotNetFileReader

Desktop Cleanup – Old Code

Here is a method of [quickly] caching prime numbers:

	// Prepare prime number cache.
	std::bitset< 10000 > bsPrimeNumbers = 0;
	bsPrimeNumbers.flip();
	bsPrimeNumbers.set( 0, false );
	bsPrimeNumbers.set( 1, false );

	// Create prime number cache.
	for( size_t x = 0; x * x < bsPrimeNumbers.size(); x++ )
	{
		if( bsPrimeNumbers.test( x ) )
		{
			for( size_t y = x * x; y < bsPrimeNumbers.size(); y += x )
				bsPrimeNumbers.set( y, false );
		}
	}

Credits to:
– Starblue: http://stackoverflow.com/questions/1042902/most-elegant-way-to-generate-prime-numbers/1043247#1043247

His implementation was in Java that I converted to C++ for a web challenge.

Desktop Cleanup – Old Code

Here’s a solution method for another internet challenge from here:
http://www.bright-shadows.net/challenges/programming/xor/tryout.php

I wrote a bot to auto-solve the answer as you have to submit the solution within a specific time, here is how to decrypt the answer:

        private void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e)
        {
            if (webBrowser1.Url.ToString().Contains("http://www.bright-shadows.net/challenges/programming/xor/tryout.php"))
            {

                string strText = webBrowser1.DocumentText.Substring(webBrowser1.DocumentText.IndexOf(''') + 1);
                string strNewText = String.Empty;
                strText = strText.Remove(strText.Length - 1, 1);

                string strXor = "C12W4BERT954";
                int xorStep = 0;

                for (int x = 0; x < strText.Length; x++)
                {
                    if (xorStep >= strXor.Length)
                        xorStep = 0;

                    strNewText += (char)(strText[x] ^ strXor[xorStep]);
                    xorStep++;
                }

                webBrowser1.Navigate("http://www.bright-shadows.net/challenges/programming/xor/solution.php?solution=" + strNewText);
            }
        }

Desktop Cleanup – Old Code

Here’s a small bit of code to read the players inventory in Final Fantasy XI.

#include <Windows.h>
#include <iostream>
#include <TlHelp32.h>

typedef struct _ITEM_ENTRY {

	unsigned char _unk1[ 40 ];
	unsigned long ItemBasePtr;
	unsigned long ItemId;
	unsigned long ItemCount;
	unsigned char _unk3[ 28 ];

} ITEM_ENTRY, *LPITEM_ENTRY;

typedef struct _MENU_HEADER {
	unsigned char _unk1[ 70 ];
	unsigned char Description[ 17 ];
} MENU_HEADER;

typedef struct _MENU_STRUCT {

	//unsigned char _unk1[ 4 ];
	unsigned long	_unk1;
	unsigned long	MenuHeader;
	unsigned long	UnknownPtr;
	unsigned long	MenuDetails;

	unsigned char	_unk3[ 60 ];

	unsigned long	Index;

} MENU_STRUCT;

DWORD GetProcess( void )
{
	PROCESSENTRY32 pe32 = { sizeof( pe32 ) };
	HANDLE hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
	if( hSnapshot == INVALID_HANDLE_VALUE )
		return 0;

	if( ! Process32First( hSnapshot, &pe32 ) )
	{
		CloseHandle( hSnapshot );
		return 0;
	}

	do {
		if( _stricmp( pe32.szExeFile, "pol.exe" ) == 0 )
		{
			CloseHandle( hSnapshot );
			return pe32.th32ProcessID;
		}
	} while( Process32Next( hSnapshot, &pe32 ) );

	CloseHandle( hSnapshot );
	return 0;
}

DWORD GetModule( DWORD dwProcessId )
{
	MODULEENTRY32 me32 = { sizeof( me32 ) };
	HANDLE hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwProcessId );
	if( hSnapshot == INVALID_HANDLE_VALUE )
		return 0;

	if( ! Module32First( hSnapshot, &me32 ) )
	{
		CloseHandle( hSnapshot );
		return 0;
	}

	do {
		if( _stricmp( me32.szModule, "ffximain.dll" ) == 0 )
		{
			CloseHandle( hSnapshot );
			return reinterpret_cast< DWORD >( me32.modBaseAddr );
		}
	} while( Module32Next( hSnapshot, &me32 ) );

	CloseHandle( hSnapshot );
	return 0;
}

int __cdecl main( int argc, char* argv[] )
{
	DWORD dwProcess = GetProcess();
	DWORD dwModule = GetModule( dwProcess );

	DWORD dwMenuPtr		= (dwModule + 0xF8882);
	DWORD dwPointer		= 0;
	HANDLE hHandle		= OpenProcess( PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, dwProcess );
	
	MENU_STRUCT menuStruct = { 0 };
	MENU_HEADER menuHeader = { 0 };
	ReadProcessMemory( hHandle, (LPVOID)dwMenuPtr, &dwPointer, 4, NULL );
	ReadProcessMemory( hHandle, (LPVOID)dwPointer, &dwPointer, 4, NULL );
	ReadProcessMemory( hHandle, (LPVOID)dwPointer, &menuStruct, sizeof( menuStruct ), NULL );
	ReadProcessMemory( hHandle, (LPVOID)menuStruct.MenuHeader, &menuHeader, sizeof( MENU_HEADER ), NULL );

	menuStruct.Index = menuStruct.Index;

	CloseHandle( hHandle );
	return 0;
}

This code is fairly old so the pointers/offsets are bound to be off. The structures probably changed since this was written so you will more then likely have to alter things for it to work as expected.

Disclaimer:
I do not own Final Fantasy XI; I am not the owner of their property or their name.
Final Fantasy XI is copyright to the following:

© 2001 – 2011 SQUARE ENIX CO., LTD. All Rights Reserved. FINAL FANTASY, SQUARE ENIX, and the SQUARE ENIX logo are registered trademarks of Square Enix Holdings Co., Ltd. Vana’diel , Tetra Master, PLAYONLINE, the PLAYONLINE logo, Rise of the Zilart, Chains of Promathia, Treasures of Aht Urhgan, and Wings of the Goddess are registered trademarks of Square Enix Co., Ltd. The Online icon is a trademark of Sony Computer Entertainment America Inc. “PlayStation” and the “PS” Family logo are registered trademarks of Sony Computer Entertainment Inc. Microsoft, Xbox, Xbox 360, Xbox LIVE, and the Xbox logos are trademarks of the Microsoft group of companies and are used under license from Microsoft. The rating icon is a registered trademark of the Entertainment Software Association. All other trademarks are the property of their respective owners. Online play requires internet connection.

Desktop Cleanup – Old Code

Continuing with the cleanup today; here are some other snippets from some SourceMod scripts I wrote for my private servers:

Double Damage – Hook to increase the damage of all weapons (x2).

/**
 * Player Hurt Event
 */
public Action:OnPlayerHurt_Event( Handle:event, const String:name[], bool:dontBroadcast )
{
	new attacker = GetClientOfUserId( GetEventInt( event, "attacker" ) );
	if( IsClientInGame( attacker ) && !IsFakeClient( attacker ) )
	{
		new dmgarmor 	= GetEventInt( event, "dmg_armor" );
		new dmghealth 	= GetEventInt( event, "dmg_health" );
		
		dmgarmor 	= dmgarmor * 2;
		dmghealth 	= dmghealth * 2;
		
		SetEventInt( event, "dmg_armor", dmgarmor );
		SetEventInt( event, "dmg_health", dmghealth );
	}
	return Plugin_Continue;
}

// Hook:
HookEvent( "player_hurt", OnPlayerHurt_Event, EventHookMode_Pre );

Auto-bhop – Forces clients to continue jumping while holding their jump button.

public Action:OnPlayerRunCmd( client, &buttons, &impulse, Float:vel[3], Float:angles[3], &weapon )
{
	if( IsPlayerAlive( client ) && IsClientInGame( client ) )
	{
		if( buttons & IN_JUMP )
		{
			if( ! ( GetEntityFlags( client ) & FL_ONGROUND ) )
			{
				buttons &= ~IN_JUMP;
			}
		}
	}
	
	return Plugin_Continue;
}

Desktop Cleanup – Old Code

This was an example of how to download the favorite icon from a website I wrote for someone on Cheat Engine’s forums.


#pragma comment( lib, "WS2_32.lib" )
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <string>

// Site to [attempt to] download icon from.
std::string g_vSite = "www.google.com";
std::string g_vIcon = "favicon.ico";

int main( int argc, TCHAR* argv[] )
{
	WSADATA wsaData = { 0 };
	if( WSAStartup( MAKEWORD( 2, 0 ), & wsaData ) != 0 )
	{
		std::cout << "WSAStartup failed with error: " << WSAGetLastError() << std::endl;
		return 0;
	}

	SOCKET sock = { 0 };
	if( ( sock = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP ) ) < 0 )
	{
		std::cout << "socket failed with error: " << WSAGetLastError() << std::endl;
		WSACleanup();
		return 0;
	}

	struct hostent* rhostent = { 0 };
	rhostent = gethostbyname( g_vSite.c_str() );

	struct sockaddr_in saddr = { 0 };
	saddr.sin_family		= AF_INET;
	saddr.sin_addr.s_addr	= *(u_long*)rhostent->h_addr_list[0];
	saddr.sin_port			= htons( 80 );

	if( connect( sock, (struct sockaddr *)&saddr, sizeof( sockaddr_in ) ) < 0 )
	{
		std::cout << "connect failed with error: " << WSAGetLastError() << std::endl;
		closesocket( sock );
		WSACleanup();
		return 0;
	}

	// Build HTTP GET request to obtain icon file.
	std::string strHttpRequest = "GET /favicon.ico HTTP/1.0rn";
	strHttpRequest += "Host: " + g_vSite + "rn";
	strHttpRequest += "rn";

	if( send( sock, strHttpRequest.c_str(), strHttpRequest.length(), 0 ) != strHttpRequest.length() )
	{
		std::cout << "send failed with error: " << WSAGetLastError() << std::endl;
		closesocket( sock );
		WSACleanup();
		return 0;
	}

	// Retrieve buffer from request.
	std::string strHttpResponse;
	char szBuffer[ 512 ] = { 0 };
	int nReadSize = 512;

	while( nReadSize > 0 )
	{
		nReadSize = recv( sock, (char*)&szBuffer, 512, NULL );
		if( nReadSize == 0 ) break;
		strHttpResponse += std::string( szBuffer ).substr( 0, nReadSize );
	}

	// Cleanup and return.
	closesocket( sock );
	WSACleanup();

	return 0;
}

References used:
http://www.zedwood.com/article/113/cpp-winsock-basic-http-connection
http://msdn.microsoft.com/en-us/library/ms738524%28v=vs.85%29.aspx