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
 alexpigna@gmail.com 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=2t=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 alexpigna@gmail.com
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 a.pigno...@sssup.it
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