safedisk 1 update, get your safedisk 1 games out (Not running just
yet, but getting there)
Ivan Leo Puoti
ivanleo at gmail.com
Thu Apr 14 14:34:13 CDT 2005
OK, here is a little summary on where we are with safedisk, here by
safedisk I always mean safedisk 1.
Safedisk protected games are packed into an encrypted ICD file, in my
case the game executable is called EMPIRES2.ICD. Safedisk is actually
made up of a little loader, empires2.exe (But this depends on the name
of the game), and a kernel mode driver, Secdrv.sys. A safedisk service
is installed, and in windows a kernel mode service is just a driver. The
loader starts the secdrv service, so I've hacked advapi32 to call the NT
function NtLoadDriver when it detects a kernel mode service. This
function, after a couple of checks, passes the call to the ntoskrnl
program I've written, Microsoft has ntoskrnl<->ntdll communication done
by a fancy exception rising/handling system, I have just gone for a
named pipe, as we don't use ntoskrnl as a real kernel (In windows
everything you do causes loads of calls to ntoskrnl, in wine ntoskrnl is
seldom used at all and only handles very few calls).
Ntoskrnl loads the driver, and it successfully initialises. At this
point the safedisk loader communicates with its driver using
DeviceIoControl, it passes an input buffer, that contains some
instructions for the driver, and an output buffer that is meant to
receive some well defined values that are meant to tell the user mode
loader if everything is OK (For example a debugger isn't loaded). The
loader also tries to get device handles for well known debuggers, this
isn't an issue for us. DeviceIoControl passes the call to
NtDeviceIoControlFile, that passes the call on to ntoskrnl. A windows
driver handles user mode IO requests via a function called
DeviceDispatchControl, it's address is put in the member of the
DEVICE_OBJECT struct that the driver's initialisation function fills for
the system (This is the DriverEntry routine). In wine currently a device
handle is a pointer to a DEVICE_OBJECT struct, guys in #reactos have
confirmed this is how things work in windows, and even if AJ thinks we
should have real file handles this approach makes no sense to me whatsoever.
DeviceDispatchControl in safedisk 1 check the control code passed to
DeviceIoControl (It must always be 0xef002407), it then reads the input
buffer, if byte 0xc in the buffer is 0x3c it checks the debug registers,
other values trigger other checks. It also checks the length of both
input and output buffers. It should then read the debug registers, and
this should rise and exception that we will somehow handle. However for
some unknown reason this doesn't happen, and the status of the IO
operation is STATUS_UNSUCCESSFUL, note that this value is in the IRP
sturct under Irp.IoStatus.Status, DispatchDeviceControl always returns
0. At this point I would like to know if other safedisk 1 protected
games yield different results. I would love to step trough secdrv.sys
with winedbg, but it just hangs or crashes. The code in ntoskrnl prints
the interesting buffer values that secdrv.sys checks for, it currently
prints
trace:ntoskrnl:NtDeviceIoControlFile
(0x40340ba8,(nil),(nil),(nil),0x4068d9c8,0xef002407,0x414e1498,0x00000514,0x414e19ac,0x00000610)
trace:ntoskrnl:driver_control driver_control is at 0x405cea80
trace:ntoskrnl:driver_control Handling IoContorl, handle is 0x40340ba8,
ControlCode is ef002407, OutputBufferLength is 610, InputBufferLength is 514
trace:ntoskrnl:driver_control InputBuffer[0xc] is 3c, InputBuffer[410] is 0
fixme:ntoskrnl:IofCompleteRequest stub!
trace:ntoskrnl:driver_control IRP_MJ_DEVICE_CONTROL returned 0, IoStatus
it c0000001, Infomation is 0
trace:ntoskrnl:driver_control Irp.UserBuffer[0x410] is 0,
Irp.UserBuffer[0x40c] is 0
In case of success Irp.UserBuffer[0x410] should be 0x00000500 and
Irp.UserBuffer[0x40c] should be 4.
All that is needed to run safedisk up to the point where it can run ATM
is at http://spazioinwind.libero.it/nonsolomicrosoft/safedisk.html
Please get all your safedisk 1 games and try it out, the more people try
it the better.
More information about the wine-devel
mailing list