CreateProcess and windbg

Hi all
not sure whether this is the most appropriate place to raise this issue but I’m hopeful that the learned folk who monitor this forum will have some ideas…

I’ve been reverse engineeering a piece of malware that manipulates it’s own file by calling CreateFile against the filename returned by GetModuleFileName. The call to CreateProcess uses a share mode of zero (ie no sharing). When the process runs, this works fine but when I step through the code in WINDBG (or in IDA for that matter), CreateProcess fails with a sharing violation (WIN32 error 0x20).

I’m guessing that this is something to do with the Debugger holding the lock on the file rather than the debuggee but am struggling to understand precisely what the difference between the two scenarios is (the debugger and the sample are both running as separate processes after all).

Any thoughts ??

Cheers

Mark

>The call to CreateProcess uses a share mode of zero (ie no sharing).

Have you stepped through CreateProcess to see where the sharing violation is
coming from? It seems overly harsh that CreateProcess would want exclusive
access to the file, so it would be interesting to see the failing operation
in the debugger versus the create without the debugger.

-scott


Scott Noone
Consulting Associate and Chief System Problem Analyst
OSR Open Systems Resources, Inc.
http://www.osronline.com

i dont think CreateProcess Takes a Sharemode Flag
BOOL CreateProcess(

LPCTSTR lpApplicationName, // pointer to name of executable module
LPTSTR lpCommandLine, // pointer to command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes, // pointer to process
security attributes
LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to thread security
attributes
BOOL bInheritHandles, // handle inheritance flag
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // pointer to new environment block
LPCTSTR lpCurrentDirectory, // pointer to current directory name
LPSTARTUPINFO lpStartupInfo, // pointer to STARTUPINFO
LPPROCESS_INFORMATION lpProcessInformation // pointer to
PROCESS_INFORMATION
);

yes CreateFile Takes a sharemode flag

#include <stdio.h>
#include <windows.h>

extern int errorprint(void);

char filename[MAX_PATH+2] = {0};
HANDLE File = NULL;

int main(void)

{
GetModuleFileName(0,filename,MAX_PATH);
printf(“process name and path is\n%s\n”,filename);
File = CreateFile(filename,GENERIC_READ |
GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
errorprint();
return 0;
}

C:\Documents and Settings\Admin\Desktop\newself>BCC32 self.c errorprint.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
self.c:
errorprint.c:
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

C:\Documents and Settings\Admin\Desktop\newself>self.exe
process name and path is
C:\Documents and Settings\Admin\Desktop\newself\self.exe
LastError Returned was
The process cannot access the file because it is being used by another
process.

C:\Documents and Settings\Admin\Desktop\newself>

wrote in message news:xxxxx@windbg…
> Hi all
> not sure whether this is the most appropriate place to raise this issue
> but I’m hopeful that the learned folk who monitor this forum will have
> some ideas…
>
> I’ve been reverse engineeering a piece of malware that manipulates it’s
> own file by calling CreateFile against the filename returned by
> GetModuleFileName. The call to CreateProcess uses a share mode of zero (ie
> no sharing). When the process runs, this works fine but when I step
> through the code in WINDBG (or in IDA for that matter), CreateProcess
> fails with a sharing violation (WIN32 error 0x20).
>
> I’m guessing that this is something to do with the Debugger holding the
> lock on the file rather than the debuggee but am struggling to understand
> precisely what the difference between the two scenarios is (the debugger
> and the sample are both running as separate processes after all).
>
> Any thoughts ??
>
> Cheers
>
> Mark
></windows.h></stdio.h>

aaargh sorry for the confusion! I’d sent this at the end of a very long day :frowning: As Raj has surmised though, it is the call to CreateFile that fails, not CreateProcess.

So the scenario is exactly as per the code sample that Raj provided except that the dwDesiredAccess (2nd) parameter is just GENERIC_READ rather than GENERIC_READ | GENERIC_WRITE. When I compile Raj’s code with this one change, it works fine from the command line but fails with INVALID_HANDLE within WINDBG (and !gle returns error 0x20) from within WINDBG.

ah yes it seems to be a weird behaviour
ollydbg does not do it

C:\Documents and Settings\Admin\Desktop\newself>self
process name and path is
C:\Documents and Settings\Admin\Desktop\newself\self.exe
LastError Returned was
The operation completed successfully.

C:\Documents and
Settings\Admin\Desktop\newself>f:\windbg\612windbg\cdb.exe -g -
G -c g;q self.exe

Microsoft (R) Windows Debugger Version 6.12.0002.633 X86
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: self.exe
Symbol search path is:
SRV*F:\symbols*http://msdl.microsoft.com/download/symbols

Executable search path is:
ModLoad: 00400000 00413000 self.exe
ModLoad: 7c900000 7c9b2000 ntdll.dll
ModLoad: 7c800000 7c8f6000 C:\WINDOWS\system32\kernel32.dll
ModLoad: 64d00000 64d33000 C:\Program Files\Alwil
Software\Avast5\snxhk.dll
ModLoad: 7e410000 7e4a1000 C:\WINDOWS\system32\USER32.DLL
ModLoad: 77f10000 77f59000 C:\WINDOWS\system32\GDI32.dll
ModLoad: 5cb70000 5cb96000 C:\WINDOWS\system32\ShimEng.dll
ModLoad: 76390000 763ad000 C:\WINDOWS\system32\IMM32.DLL
ModLoad: 77dd0000 77e6b000 C:\WINDOWS\system32\ADVAPI32.dll
ModLoad: 77e70000 77f02000 C:\WINDOWS\system32\RPCRT4.dll
ModLoad: 77fe0000 77ff1000 C:\WINDOWS\system32\Secur32.dll
process name and path is
C:\Documents and Settings\Admin\Desktop\newself\self.exe
LastError Returned was
The process cannot access the file because it is being used by another
process.

C:\Documents and Settings\Admin\Desktop\newself>

wrote in message news:xxxxx@windbg…
> aaargh sorry for the confusion! I’d sent this at the end of a very long
> day :frowning: As Raj has surmised though, it is the call to CreateFile that
> fails, not CreateProcess.
>
> So the scenario is exactly as per the code sample that Raj provided except
> that the dwDesiredAccess (2nd) parameter is just GENERIC_READ rather than
> GENERIC_READ | GENERIC_WRITE. When I compile Raj’s code with this one
> change, it works fine from the command line but fails with INVALID_HANDLE
> within WINDBG (and !gle returns error 0x20) from within WINDBG.
>

>When I compile Raj’s code with this one change, it works fine from the

command line but fails with INVALID_HANDLE within WINDBG >and !gle returns
error 0x20) from within WINDBG.

Interesting, it does appear that WinDBG keeps a handle open to the file (you
can see if in Process Monitor). That handle has full sharing enabled though,
so why not just doink (technical term for, “edit”) the share mode parameter
to the CreateFile call to specify read sharing? If you can step the code you
should be able to just change the memory with eb.

-scott


Scott Noone
Consulting Associate and Chief System Problem Analyst
OSR Open Systems Resources, Inc.
http://www.osronline.com

visual studios debuggger and ollydbg does not display the behaviour idafree
windbg and old td32 dispalys the behaviour

what is the right behaviour ?

anyway

here is a process mon stack for windbg

Date & Time: 2/24/2011 8:53:45 PM
Event Class: File System
Operation: IRP_MJ_CREATE
Result: SHARING VIOLATION
Path: C:\Documents and Settings\Admin\Desktop\newself\self.exe
TID: 2512
Duration: 0.0000146
Desired Access: Generic Read
Disposition: Open
Options: Synchronous IO Non-Alert, Non-Directory File
Attributes: N
ShareMode: None
AllocationSize: n/a

0 fltMgr.sys FltpPerformPreCallbacks + 0x2d4 0xf7434888
C:\WINDOWS\System32\Drivers\fltMgr.sys
1 fltMgr.sys FltpPassThroughInternal + 0x32 0xf74362a0
C:\WINDOWS\System32\Drivers\fltMgr.sys
2 fltMgr.sys FltpCreateInternal + 0x63 0xf7443217
C:\WINDOWS\System32\Drivers\fltMgr.sys
3 fltMgr.sys FltpCreate + 0x258 0xf7443742
C:\WINDOWS\System32\Drivers\fltMgr.sys
4 ntkrnlpa.exe IopfCallDriver + 0x31 0x804ee129
C:\WINDOWS\system32\ntkrnlpa.exe
5 aswMon2.SYS aswMon2.SYS + 0xa34 0xa93f8a34
C:\WINDOWS\System32\Drivers\aswMon2.SYS
6 ntkrnlpa.exe IopfCallDriver + 0x31 0x804ee129
C:\WINDOWS\system32\ntkrnlpa.exe
7 ntkrnlpa.exe ObpLookupObjectName + 0x56a 0x805b4d3c
C:\WINDOWS\system32\ntkrnlpa.exe
8 ntkrnlpa.exe ObOpenObjectByName + 0xeb 0x805b10e5
C:\WINDOWS\system32\ntkrnlpa.exe
9 ntkrnlpa.exe IopCreateFile + 0x407 0x8056b295
C:\WINDOWS\system32\ntkrnlpa.exe
10 ntkrnlpa.exe IoCreateFile + 0x8e 0x8056bc0c
C:\WINDOWS\system32\ntkrnlpa.exe
11 ntkrnlpa.exe NtCreateFile + 0x30 0x8056e31e
C:\WINDOWS\system32\ntkrnlpa.exe
12 ntkrnlpa.exe KiFastCallEntry + 0xf8 0x8053d658
C:\WINDOWS\system32\ntkrnlpa.exe
13 kernel32.dll CreateFileA + 0x30 0x7c801a53
C:\WINDOWS\system32\kernel32.dll
14 self.exe self.exe + 0x1192 0x401192 C:\Documents and
Settings\Admin\Desktop\newself\self.exe
15 self.exe self.exe + 0x7d12 0x407d12 C:\Documents and
Settings\Admin\Desktop\newself\self.exe

same for msdev

Date & Time: 2/24/2011 8:54:59 PM
Event Class: File System
Operation: IRP_MJ_CREATE
Result: SUCCESS
Path: C:\Documents and Settings\Admin\Desktop\newself\self.exe
TID: 3264
Duration: 0.0000224
Desired Access: Generic Read
Disposition: Open
Options: Synchronous IO Non-Alert, Non-Directory File
Attributes: N
ShareMode: None
AllocationSize: n/a
OpenResult: Opened

stack

0 fltMgr.sys FltpPerformPreCallbacks + 0x2d4 0xf7434888
C:\WINDOWS\System32\Drivers\fltMgr.sys
1 fltMgr.sys FltpPassThroughInternal + 0x32 0xf74362a0
C:\WINDOWS\System32\Drivers\fltMgr.sys
2 fltMgr.sys FltpCreateInternal + 0x63 0xf7443217
C:\WINDOWS\System32\Drivers\fltMgr.sys
3 fltMgr.sys FltpCreate + 0x258 0xf7443742
C:\WINDOWS\System32\Drivers\fltMgr.sys
4 ntkrnlpa.exe IopfCallDriver + 0x31 0x804ee129
C:\WINDOWS\system32\ntkrnlpa.exe
5 aswMon2.SYS aswMon2.SYS + 0xa34 0xa93f8a34
C:\WINDOWS\System32\Drivers\aswMon2.SYS
6 ntkrnlpa.exe IopfCallDriver + 0x31 0x804ee129
C:\WINDOWS\system32\ntkrnlpa.exe
7 ntkrnlpa.exe ObpLookupObjectName + 0x56a 0x805b4d3c
C:\WINDOWS\system32\ntkrnlpa.exe
8 ntkrnlpa.exe ObOpenObjectByName + 0xeb 0x805b10e5
C:\WINDOWS\system32\ntkrnlpa.exe
9 ntkrnlpa.exe IopCreateFile + 0x407 0x8056b295
C:\WINDOWS\system32\ntkrnlpa.exe
10 ntkrnlpa.exe IoCreateFile + 0x8e 0x8056bc0c
C:\WINDOWS\system32\ntkrnlpa.exe
11 ntkrnlpa.exe NtCreateFile + 0x30 0x8056e31e
C:\WINDOWS\system32\ntkrnlpa.exe
12 ntkrnlpa.exe KiFastCallEntry + 0xf8 0x8053d658
C:\WINDOWS\system32\ntkrnlpa.exe
13 kernel32.dll CreateFileA + 0x30 0x7c801a53
C:\WINDOWS\system32\kernel32.dll
14 self.exe self.exe + 0x1192 0x401192 C:\Documents and
Settings\Admin\Desktop\newself\self.exe
15 self.exe self.exe + 0x7d12 0x407d12 C:\Documents and
Settings\Admin\Desktop\newself\self.exe

cant find any difference though in the summery except result

“Scott Noone” wrote in message news:xxxxx@windbg…
> >When I compile Raj’s code with this one change, it works fine from the
> >command line but fails with INVALID_HANDLE within WINDBG >and !gle
> >returns error 0x20) from within WINDBG.
>
> Interesting, it does appear that WinDBG keeps a handle open to the file
> (you can see if in Process Monitor). That handle has full sharing enabled
> though, so why not just doink (technical term for, “edit”) the share mode
> parameter to the CreateFile call to specify read sharing? If you can step
> the code you should be able to just change the memory with eb.
>
> -scott
>
> –
> Scott Noone
> Consulting Associate and Chief System Problem Analyst
> OSR Open Systems Resources, Inc.
> http://www.osronline.com
>
>

It’s strange for sure. I was able to get around it by hacking the share mode parameter on the stack prior to the CreateFile call but was really just curious about why it happens…

As Raj has pointed out it works fine with the Visual Studio 10 debugger but IDA (in my case the retail version but it sounds like this doesn’t matter) does the same as WINDBG (and no, I haven’t configured IDA to use WINDBG)

Very odd but I’m happy to attribute this to a quirk of the debugger. Thanks both for your responses though.