August 19, 2011

[Windows Programming] : Exception Generation during process creation or system command execution


Problem Description


During my windows porting activity (Existing code base in *ix - CPP programming language)
I came across a very strange problem

The project code bases uses many system command for various activity,
and one such operation is to untar (unrar in windows) the package to be launched.

Strangely the problem faced was that the unrar command used was not working as expected in XP SP3 patch.
Instead for both error and success scenario strange error code was displayed.
Below steps provides an insight with the investigation steps and the final end result.


Investigation Steps

Step 1: The initial suspect was related to compatibility of system command in Windows.
Unlike *ix, where the command is very well defined, it was hard to find out a suitable documentation for the same in
windows.

So immediately suspect was API issue (compatibility problem).

Step 2: Next the focus shifted to an well established, command execution methodology. Immediate reference came
from MSDN content -

http://msdn.microsoft.com/en-us/library/ms682425%28v=vs.85%29.aspx

Step 3: A sample program was derived - which used the createProcess API was used for untarring.

Sample code looked as shown below

1:  int main()  
2:  {  
3:  string ProgramName = "C:\\Program Files\\WinRAR\\WinRAR.exe";  
4:  STARTUPINFO StartupInfo;  
5:  PROCESS_INFORMATION ProcessInfo;  
6:  memset(&StartupInfo, 0, sizeof(STARTUPINFO));  
7:  memset(&ProcessInfo, 0, sizeof(PROCESS_INFORMATION);  
8:  if (CreateProcess((LPCTSTR)ProgramName.c_str(),(LPCTSTR)"WinRAR.exe x -y -ibck d:\\abc.tar d:\\"),NULL,  
9:  NULL,  
10:  FALSE,  
11:  NORMAL_PRIORITY_CLASS,  
12:  NULL,  
13:  NULL,  
14:  &StartupInfo,  
15:  &ProcessInfo) == 0)  
16:  {  
17:  string tmpStr("Error executing");  
18:  tmpStr += ProgramName;  
19:  cout<<"StmtDesigner"<<<"createprocess dword="" exitcode="0;" if="" span="" string="" tmpstr="">  
20:  }  
21:  CloseHandle(ProcessInfo.hProcess);  
22:  CloseHandle(ProcessInfo.hThread);  
23:  getch();  
24:  return 0;  
25:  }



In this case strangely,
SP2 provided expected result - i.e 0 for success and 1 (non-zero) for failure.
SP3 provided unexpected result - i.e 3221225477 for both success and failure.

Step 4:
The exit code value - 3221225477 was very critical, now when this was transformed
into HEX,it represented - C0000005 - which represents access violation in windows.
Now the investigation took a turn on what could have lead to the problem.

Step 5:
With lot of google'ing and detailed search, It was found that a good utility
called "Process Monitor" would mimic the functionality of strace in Unix.

http://technet.microsoft.com/en-us/sysinternals/bb896645

Was downloaded and on SP3 machine and the sample program above was run with
monitor tool.

Step 6:
Process Monitor helped (with very good filtering feature) to find out that
WinRar process exited with exception.

This was noted as an event in the Process Monitor,
Further analysis of the stack during the Winrar exit event showed that the
$WINDOWS/system32/ntdll.dll interacted with one of the proprietary library present
in the same path thus the exit status was not captured correctly as ntdll.dll
was trying to access some function of proprietary library - causing access violation.

This was cross confirmed by SP2 machine - which did not have this dll file
(and program
was executed successfully).

Also after renaming/removing the proprietary library from system32 directory,
the operation succeeded even in SP3 operation (both createProcess and system command)

Take Away's

1. It is still unclear why the presence of proprietary application library in
$WINDOWS/system32 caused ntdll.dll to fail thread/process exit for WinRar application.

2. Exceptions are also thrown by the API's GetExitCodeProcess.
So it is not restricted to a range of values.

3. Placing proprietary application in the system32 location was not a good idea.
No thought on its impact was done.

4. Process Monitor is an excellent tool and is one of the must haves for the windows

developer.

5. Whenever C0000005 and other exceptions are the outcome of a program, program and
its system dependency must be thoroughly checked for all kinds of violation
(In this case an unwanted library causing some kind of interference).

6. Initial suspect on SP2/SP3 difference proved futile and invalid,
afterall looks like windows is maintaining good backward compatibility :).


Regards,
Tech Unravel
Supreme Debugging







No comments:

Post a Comment