Re: [PATCH] Support for game DRM which overwrite the GS segment selector

2013-02-03 Thread Alessandro Pignotti
Il giorno sab, 02/02/2013 alle 12.10 +0100, Austin English ha scritto:
> On Jan 31, 2013 8:15 AM, "Alessandro Pignotti"
>  wrote:
> >
> > Hi again,
> >
> > I've quickly implemented the aforementioned idea of fixing the
> segment
> > in the segfault handler when needed. I'm attaching my proposed
> patch.
> >
> > Alessandro
> >
> > Il giorno mer, 30/01/2013 alle 16.44 +0100, Alessandro Pignotti ha
> > scritto:
> > > Hi everyone,
> > >
> > > I'm trying to get a specific game which employs a seemingly custom
> > > protection scheme to work. The DRM does various bad things as
> usual, but
> > > a very bad one is manipulating to GS segment selector and setting
> it to
> > > a NULL segment. The GS segment is used by libc though in various
> ways
> > > (stack protection and syscall support, and probably others).
> > >
> > > I managed to get the activation procedure to go further and
> further by
> > > enclosing each offending syscall using the following 2 macros.
> > >
> > > #define SAFE_GS_START \
> > > do { \
> > > wine_set_gs(ntdll_get_thread_data()->gs); \
> > > do
> > >
> > > #define SAFE_GS_END \
> > > while(0); \
> > > } while(0)
> > >
> > > Still, this method is very cumbersome since system calls happens
> in many
> > > places even outside of ntdll. Fixing the GS is also needed to
> support
> > > sigsetjmp which is used by wine's exception handling.
> > >
> > > I'd like to ask for feedback about what would be a sane way of
> > > supporting this application. A possible solution would be to
> modify
> > > wine's segfault handler to check if the instruction has a GS
> prefix
> > > (0x65 IIRC) and try to execute the instruction again after fixing
> the
> > > GS.
> > >
> > > Please keep me in CC since I'm not subscribed to the ML.
> > >
> > > Regards,
> > > Alessandro Pignotti
> 
> Out of curiosity, what game is this? What protection does Protection
> ID show it uses?
> 
It's report as StarForce 32 Bit v5.70.040.000. The game is 'Of Orcs And
Men', the problem is also reported in wine forums

http://forum.winehq.org/viewtopic.php?f=2&t=17609

Alessandro





Re: [PATCH] Support for game DRM which overwrite the GS segment selector

2013-02-02 Thread Austin English
On Jan 31, 2013 8:15 AM, "Alessandro Pignotti" 
wrote:
>
> Hi again,
>
> I've quickly implemented the aforementioned idea of fixing the segment
> in the segfault handler when needed. I'm attaching my proposed patch.
>
> Alessandro
>
> Il giorno mer, 30/01/2013 alle 16.44 +0100, Alessandro Pignotti ha
> scritto:
> > Hi everyone,
> >
> > I'm trying to get a specific game which employs a seemingly custom
> > protection scheme to work. The DRM does various bad things as usual, but
> > a very bad one is manipulating to GS segment selector and setting it to
> > a NULL segment. The GS segment is used by libc though in various ways
> > (stack protection and syscall support, and probably others).
> >
> > I managed to get the activation procedure to go further and further by
> > enclosing each offending syscall using the following 2 macros.
> >
> > #define SAFE_GS_START \
> > do { \
> > wine_set_gs(ntdll_get_thread_data()->gs); \
> > do
> >
> > #define SAFE_GS_END \
> > while(0); \
> > } while(0)
> >
> > Still, this method is very cumbersome since system calls happens in many
> > places even outside of ntdll. Fixing the GS is also needed to support
> > sigsetjmp which is used by wine's exception handling.
> >
> > I'd like to ask for feedback about what would be a sane way of
> > supporting this application. A possible solution would be to modify
> > wine's segfault handler to check if the instruction has a GS prefix
> > (0x65 IIRC) and try to execute the instruction again after fixing the
> > GS.
> >
> > Please keep me in CC since I'm not subscribed to the ML.
> >
> > Regards,
> > Alessandro Pignotti

Out of curiosity, what game is this? What protection does Protection ID
show it uses?



[PATCH] Support for game DRM which overwrite the GS segment selector

2013-01-30 Thread Alessandro Pignotti
Hi again,

I've quickly implemented the aforementioned idea of fixing the segment
in the segfault handler when needed. I'm attaching my proposed patch.

Alessandro

Il giorno mer, 30/01/2013 alle 16.44 +0100, Alessandro Pignotti ha
scritto:
> Hi everyone,
> 
> I'm trying to get a specific game which employs a seemingly custom
> protection scheme to work. The DRM does various bad things as usual, but
> a very bad one is manipulating to GS segment selector and setting it to
> a NULL segment. The GS segment is used by libc though in various ways
> (stack protection and syscall support, and probably others).
> 
> I managed to get the activation procedure to go further and further by
> enclosing each offending syscall using the following 2 macros.
> 
> #define SAFE_GS_START \
> do { \
> wine_set_gs(ntdll_get_thread_data()->gs); \
> do
> 
> #define SAFE_GS_END \
> while(0); \
> } while(0)
> 
> Still, this method is very cumbersome since system calls happens in many
> places even outside of ntdll. Fixing the GS is also needed to support
> sigsetjmp which is used by wine's exception handling.
> 
> I'd like to ask for feedback about what would be a sane way of
> supporting this application. A possible solution would be to modify
> wine's segfault handler to check if the instruction has a GS prefix
> (0x65 IIRC) and try to execute the instruction again after fixing the
> GS.
> 
> Please keep me in CC since I'm not subscribed to the ML.
> 
> Regards,
> Alessandro Pignotti

>From 35d5b875c7ca63845ddb68f1036f58d31ff4957e Mon Sep 17 00:00:00 2001
From: Alessandro Pignotti 
Date: Wed, 30 Jan 2013 17:09:15 +0100
Subject: [PATCH] Restore the GS selector when crashing (if needed)

---
 dlls/ntdll/signal_i386.c |8 
 1 file changed, 8 insertions(+)

diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index 4a83a70..8e9e46b 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -1863,6 +1863,14 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
 return;
 }
 
+/* special handling for segment faults of the GS segment */
+unsigned char* opcode=(unsigned char*)EIP_sig(context);
+if (get_trap_code(context) == TRAP_x86_PROTFLT && *opcode==0x65)
+{
+GS_sig(context)=ntdll_get_thread_data()->gs;
+return;
+}
+
 rec = setup_exception_record( context, stack, fs, gs, raise_segv_exception );
 if (rec->ExceptionCode == EXCEPTION_STACK_OVERFLOW) return;
 
-- 
1.7.10.4