Case Of The Missing Ini Files – A WinDbg Reconstruction

An application was reported by the customer as “incompatible” with Windows 7 as it was “crashing” It was an in-house app developed by the customer to provide automated updates to their in-house applications. However the method of configuring the app was long forgotten.

I got a copy and installed it on a Windows 8.1 machine, and sure enough it seemed to crash…

image

This looked like a Windows Application Crash Box, but not quite. It was a customized one, and clicking click here we got a useful error message:

image

Interestingly even on a test machine provided for Windows XP the same “crash” occurred, as the .ini files has been delivered separately from the MSI installer.

So I then created a blank client.ini file in that location requested this resulted in a new error message:

image

Normally in this case I’d like to use Rohitab’s API Monitor (http://www.rohitab.com/apimonitor), however it uses API hooking methods that may make some apps unstable, and in this case using the API monitor function for INI functions caused the app to not operate properly. So we go to use WinDbg…

Ok so we know it’s looking for these 3 values, but what  “AppName” was being used in the INI file? That is the section of the INI file in square brackets. To find out I opened the EXE with WinDbg, from the Windows SDK, and set a breakpoint on the Windows API used to read INI files.

bp Kernel32!GetPrivateProfileStringA [enter]

I then hit g [enter] to start executing the app. We quickly hit our breakpoint:

image

From MSDN we can see this function is called with the following parameters http://msdn.microsoft.com/en-us/library/windows/desktop/ms724353(v=vs.85).aspx

DWORD WINAPI GetPrivateProfileString(
_In_   LPCTSTR lpAppName,
_In_   LPCTSTR lpKeyName,
_In_   LPCTSTR lpDefault,
_Out_  LPTSTR lpReturnedString,
_In_   DWORD nSize,
_In_   LPCTSTR lpFileName );

We also know the almost all Windows API functions use the STDCALL calling convention, Parameters are pushed from right to left and the callee cleans the stack. Function names are decorated by a leading underscore and a trailing @-sign followed by the number of bytes of parameters taken by the function. (http://blogs.msdn.com/b/oldnewthing/archive/2004/01/08/48616.aspx) In assembly it looks something like this:

DWORD __stdcall GetPrivateProfileStringA(LPCSTR lpAppName, LPCSTR lpKeyName, LPCSTR lpDefault, LPSTR lpReturnedString, DWORD nSize, LPCSTR lpFileName)
public _GetPrivateProfileStringA@24_GetPrivateProfileStringA@24 proc near
lpAppName= dword ptr  8
lpKeyName= dword ptr  0Ch
lpDefault= dword ptr  10h
lpReturnedString= dword ptr  14h
nSize= dword ptr  18h
lpFileName= dword ptr  1Ch

 

When a function is entered ESP register points to the return address pushed on the stack by the call instruction (that is, previous contents of EIP register). Any argument in stack of higher address then entry ESP is pushed by caller before the call is made; so the first argument is at offset +4 from ESP (EIP is 4 bytes wide), plus 4 more bytes once the EBP is pushed on the stack. Because our script is running before EBP is pushed on the stack, we find our first parameter at ESP+4. (More examples of the different x86 calling conventions with Microsoft C and GCC compilers is here http://en.wikibooks.org/wiki/X86_Disassembly/Calling_Convention_Examples )

We can now build a WinDbg script to set the breakpoint on GetPrivateProfileStringA, but also output the parameters to the WinDbg Screen, and automatically continue:

bp Kernel32!GetPrivateProfileStringA "r @$t0 = poi(@esp+4);r @$t1 = poi(@esp+8);r @$t2 = poi(@esp+0xC);r @$t3 = poi (@esp+0x18);.printf \"App Name: %ma Key Name: %ma Default: %ma Filename: %ma\",@$t0,@$t1,@$t2,@$t3;.echo;g"

 

The break point command when expanded out looks like this:

r @$t0 = poi(@esp+4);
r @$t1 = poi(@esp+8);
r @$t2 = poi(@esp+0xC);
r @$t3 = poi (@esp+0x18);
.printf \”App Name: %ma Key Name: %ma Default: %ma Filename: %ma\”,@$t0,@$t1,@$t2,@$t3;.echo;g”

 

We now run WinDbg with this command we get info about what INI parameters are being looked for. I then built up the INI file with “guessed” values until the original error was gone.

We then found a new error “Server.ini” not found, we repeated process and built that. The WinDbg output with our breakpoint script then looks like this:

App Name: Settings Key Name: Token Default:  Filename: C:\Program Files (x86)\Launcher\Client.Ini
App Name: Settings Key Name: Title Default:  Filename: C:\Program Files (x86)\Launcher\Client.Ini
App Name: Settings Key Name: ExeFile Default:  Filename: C:\Program Files (x86)\Launcher\Client.Ini
App Name: Settings Key Name: Description Default:  Filename: C:\Program Files (x86)\Launcher\Client.Ini
App Name: Settings Key Name: SupportName Default: the IT Help Desk Filename: C:\Program Files (x86)\Launcher\Client.Ini
App Name: Settings Key Name: SupportPhone Default: 12-3456 Filename: C:\Program Files (x86)\Launcher\Client.Ini
App Name: Settings Key Name: SupportEMail Default: IT.HelpDesk@company.com.au Filename: C:\Program Files (x86)\Launcher\Client.Ini
App Name: Server1 Key Name: Path Default:  Filename: C:\Program Files (x86)\Launcher\Client.Ini
App Name: Server1 Key Name: Description Default:  Filename: C:\Program Files (x86)\Launcher\Client.Ini
App Name: Server1 Key Name: Start Default: 1/1/100 Filename: C:\Program Files (x86)\Launcher\Client.Ini
App Name: Server1 Key Name: End Default: 31/12/9999 Filename: C:\Program Files (x86)\Launcher\Client.Ini
App Name: Server2 Key Name: Path Default:  Filename: C:\Program Files (x86)\Launcher\Client.Ini

 

I had specified the “path” in my client.ini to go to C:\SUPPORT, and this was where server.ini was loaded from:

App Name: Settings Key Name: Token Default:  Filename: C:\Support\Server.Ini
App Name: Env1 Key Name: Folder Default:  Filename: C:\Support\Server.Ini
App Name: Env1 Key Name: Description Default:  Filename: C:\Support\Server.Ini
App Name: Env1 Key Name: ForceCopy Default: False Filename: C:\Support\Server.Ini
App Name: Env1 Key Name: AllUsers Default: False Filename: C:\Support\Server.Ini
App Name: Env1 Key Name: chentiangemalc Default: False Filename: C:\Support\Server.Ini
App Name: Env1 Key Name: CompareFileSize Default: False Filename: C:\Support\Server.Ini
App Name: Env2 Key Name: Folder Default:  Filename: C:\Support\Server.Ini
App Name: Extension Maps Key Name: Ext1 Default:  Filename: C:\Support\Server.Ini

 

With all this we found not only the app worked fine on Windows 8.1, I had it updating a copy of “notepad” using a client.ini in the format:

[Settings]
Token=NOTEPAD
Title=Notepad
ExeFile=notepad.exe
Description=Notepad
SupportName=Notepad
SupportPhone=12345Support
EMail=notepadsupport@support.com
[Server1]Path=C:\Support

 

And a server.ini in C:\Support like this

[Settings]Token=NOTEPAD
[Env1]
Folder=Notepad
Description=Crappy Apps
ForceCopy=True
AllUsers=True
chentiangemalc=True
CompareFileSize=True

 

Where chentiangemalc was the current logged in username. I then put notepad in C:\support\notepad\notepad.exe and it would install the EXE into C:\Program Files (x86)\Launcher

With this information we were able to scan servers for server.ini and we ended up finding a copy, pointing to this would deploy the application configured in the ini. Using the info from the .ini we were able to determine users the app was deployed to and move the app into a more modern SCCM deployment method.

About chentiangemalc

specializes in end-user computing technologies. disclaimer 1) use at your own risk. test any solution in your environment. if you do not understand the impact/consequences of what you're doing please stop, and ask advice from somebody who does. 2) views are my own at the time of posting and do not necessarily represent my current view or the view of my employer and family members/relatives. 3) over the years Microsoft/Citrix/VMWare have given me a few free shirts, pens, paper notebooks/etc. despite these gifts i will try to remain unbiased.
This entry was posted in API Monitor, Application Compatibility, Debugging, Hacking, Win32, WinDbg. Bookmark the permalink.

One Response to Case Of The Missing Ini Files – A WinDbg Reconstruction

  1. Miha Pecnik says:

    Your troubleshooting skills are simply amazing. Well done, as usual.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s