News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Reading and writing data to a pipe

Started by colinr, September 04, 2011, 06:33:04 PM

Previous topic - Next topic

colinr

Hi Guys,

I am hoping one of you guru's can point me in the right direction.

I am writing a test app at the moment which uses CreatePipe followed by CreateProcess to load a system executable called DiskPart.exe.

In the debugger (OllyDbg) i can issue commands to DiskPart and read back the responce using the WriteFile and ReadFile functions without any problem.

However, during normal use, this does not work and I presume it's because the code is executing to quickly, by this I mean that the time difference between me issuing a command and then reading back the responce does not give DiskPart enough time to complete the task i instructed it to carry out.

Therefore, I am after a solution where I can only read back the responce when DiskPart has finished the task.

Ideally I don't want to put set wait times in the code as this could become problematic on other computers.

Thanks for taking the time to read this, Colin.

dedndave

you can probably use GetExitCodeProcess to get the return code
you have to create the process with PROCESS_QUERY_INFORMATION access right
you will also need the process handle, which is in the PROCESS_INFORMATION structure

if the return code is STILL_ACTIVE, use Sleep to wait some time period (something in the 10 to 50 mS range should work)
then, get the code again

a problem with this is that if STILL_ACTIVE (103h) is returned as a valid return code, you won't know it has terminated   :P
most processes, especially those written by MS, avoid returning that value

another way to go is to use ShellExecute - i think you could make that work, but it's more difficult

qWord

Quote from: colinr on September 04, 2011, 06:33:04 PMIn the debugger (OllyDbg) i can  [...] during normal use, this does not work
maybe a rights problem - try to start your program as administrator.
FPU in a trice: SmplMath
It's that simple!

colinr

@qword, it's definitely because I'm single stepping the code, the spawned application gets to finish it's task with loads of time to spare!

@dedndave, thanks for that info, I'll try it later on this evening, time permitting.  Just one more point, I don't know how familiar you are with DiskPart, but it seems to run in its own shell, instead of having C:\> as the prompt, it is DISKPART>. 

To exit back to the DOS prompt you have to type quit.

Now here might be the next problem, I intend to pipe multiple commands to diskpart one at a time and obviously retrieve each responce as they happen, would the GetExitCodeProcess still work in this instance as diskpart does not actually terminate, it just becomes idle, resting at the DISKPART> prompt between commands.  It would not be practical to exit diskpart after each command as it takes about 3-4 seconds to enumerate the disks when it is executed.

I did try to interface with the Virtual Disk Service about a year ago without luck as it heavily relies on COM, and not knowing any C whatsoever, it was a non runner for me.

Diskpart drives the VDS and i think it's the easiest (not necessarily the best) way of interacting with the VDS for me.

Thanks to both of you, Colin.

dedndave

well - you have to pipe, perhaps, several commands before something happens   :P
i would try to arrange the code so that you exit after each operation that reads or writes the disk
write a "wrapper" routine so you can pump commands through, waiting for DiskPart to exit and returning a result code
the program will not execute the exit command until the operation has completed

i forget the details of how to use DiskPart
if you can execute several commands through the command line, you may be able to do away with piping
you could also create a script file and do it that way

if you want to use the pipe approach, you can see when a command has finished by apperance of the prompt
for DiskPart, i think that's a hyphen "-"

qWord

Quote from: colinr on September 04, 2011, 08:20:09 PM
@qword, it's definitely because I'm single stepping the code, the spawned application gets to finish it's task with loads of time to spare!
ReadFile normally blocks until the specified number of bytes has been read or a handle with write access to the pipe/file has been closed (AFAIK) ...
FPU in a trice: SmplMath
It's that simple!

dedndave

from the documentation....

QuoteWhen using the DiskPart command as a part of a script, it is recommended that you complete all of the
DiskPart operations together as part of a single DiskPart script. You can run consecutive DiskPart scripts,
but you must allow at least 15 seconds between each script for a complete shutdown of the previous
execution before running the DiskPart command again in successive scripts. Otherwise, the successive
scripts might fail. You can add a pause between consecutive DiskPart scripts by adding the timeout /t 15
command to your batch file along with your DiskPart scripts.

http://technet.microsoft.com/en-us/library/cc766465%28WS.10%29.aspx

15 seconds seems like an awfully long time   :P

can you be more specific as to what you are trying to do ?
are you creating partitions ?

i would probably use MbrWizard - the older commandline version
it has one small bug
certain values need to be specified in hex, followed by 'h'

http://mbrwizard.com/

click the "Downloads" tab - then the "Legacy" tab
version 2.0b is available for 32 and 64-bit OS's

colinr

@dendave

It's actually a small GUI for a forensic application, well actually Windows 7 PE.

The app will be used to set disks to read-only/read-write and assign drive/unassign drive letters to volumes.

Not too intense but initially, the app will set all disks to read-only to prevent any writes, then the user will use the GUI to enable read/write and/or assign drive letters to disks of their choice.

It does work at the moment, a friend of mine who is more than capable at C programming wrote a DLL for me to access the VDS to carry out all of the above actions with the exception of assigning drive letters to disks, however, due to work commitments, he is unable to finish the project, therefore, I've decided to write new code to pipe commands to diskpart then parse the resulting text returned to then display to the end user in a GUI.

Hope this explains what I'm after, Colin.

dedndave

that being the case, MBRWizard should work for you
not sure if it will change drive letters, though

dedndave

i seem to recall something about drive letters in WMI
if you use the forum search tool, you may find some info on WMI


colinr

Slightly off topic, but I do have another idea!

Using OllyDbg, i have found the precise location where DiskPart outputs to the screen, is there anyway that I can patch DiskPart at this location to jump into my code, the I can intercept the strings without using the read pipe, for instance, redirect Int x to point to my code or even directly jump?

It may not be possible on 8086 machines, due to protected memory, however, going back 20 years, it was perfectly possible to do on 68000 machines.

My idea would be to load DiskPart as an executable from my code, but do not execute it at that point, patch, then execute?


dedndave

you can do that, although it probably wouldn't be considered "clean"   :P
all you need is the handle to the console window

        INVOKE  GetConsoleWindow
        mov     hConsole,eax


dedndave

hang on - lol
that won't work for what you want
you have to enumerate processes and find the one you want, then get the window handle for it
a lot of code, but do-able

not a great way to go, anyways   :P

however, you can easily redirect console output to a text file and open and read that

colinr

So just to clarify, would I still set up the write pipe and load diskpart with create process?

then use getconsole window to find the memory address of the oep of diskpart?

How would one go about redirecting, lets say int3 then start diskpart from its loaded but not executing state?

you will have to excuse my lack of understanding on this, its about 20 years ago that I attempted anything like this!