[Bug 10273] satisfy SafeDisc 2.x heuristic API analyzer by "adjusting" API exports/entry statistics of wine builtins
wine-bugs at winehq.org
wine-bugs at winehq.org
Mon Nov 5 15:46:22 CST 2007
http://bugs.winehq.org/show_bug.cgi?id=10273
--- Comment #18 from Anastasius Focht <focht at gmx.net> 2007-11-05 15:46:21 ---
Hello,
--- quote ---
I don't think we can drop -fPIC, some distros don't allow text relocations, and
we can't guarantee that the specified load address will always be free.
--- quote ---
Pity .. so we have to think about other solutions.
--- quote ---
And changing the location produces even worse c2 results for
gdi32.
--- quote ---
Thats something I wondered about too. I disassembled and compared the entry
code of the first checked exports - it did not change at all: same stack frame,
same location of __i686.get_pc_thunk.bx().
Usually within 8 instruction range, which makes it "bad guy".
So c2 must include additional information from somewhere.
--- quote ---
So it seems it is the fact that there is a call at all in these first 8
instructions that safedisc considers "bad".
--- quote ---
True, any instruction which transfers execution flow within that range seems to
be considered bad by analyzer (jmp, jcond, call ...) - regardless of the
destination (within own .text section other outside).
Though "outside" destinations seem to have "modifier" effect on c3.
They probably analyzed windows API entry code and made up some statistics how
many instructions are needed to safely detect any "hostile" execution flow
transfer (jump trampolines) without having too much false positives.
Besides there are other ways to trace/hook system calls without the need to
overwrite opcodes on entry code ;-)
I did some more testing with my custom "backdoor" dll and presented the
analyzer some lengthy code sequences (which do just nothing but waste
instructions + cpu cycles).
"t_x" = testcase x
"exp" = exports
t_1: 10 exp, seq len: 20 instr, standard stack frame (ebp), register math
t_2: 9 exp, seq len: 20 instr, standard stack frame (ebp)
1 exp, seq len: 6 instr, standard stack frame (ebp)
t_3: 5 exp, seq len: 20 instr, standard stack frame (ebp)
5 exp, seq len: 6 instr, standard stack frame (ebp)
t_4: 10 exp, seq len: 10 instr, standard stack frame (ebp), 9 x nop + 1 x ret
t1 t2 t3 t4 condition (cx < th)
--------------------------------------------------------------------
c1: 0x00 0x0A 0x32 0x00 0x5F
c2: 0x00 0x01 0x19 0x00 0x3C
c3: 0x00 0x00 0x00 0x00 0x5A
The instruction classes used seem to have no influence. The disassembler only
treats any control transfer instructions special (including ret).
So if we pad the entry code at least 8-9 instructions long with NOP or other
padding opcodes we should get around these idiotic checks.
For testing I abused the wine tools and wine's relay thunk feature.
Seemed to me quickest solution for testing, sorry for that ;-)
--- snip ---
diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c
index 8df5b85..9164827 100644
--- a/tools/winebuild/spec32.c
+++ b/tools/winebuild/spec32.c
@@ -124,7 +124,16 @@ static void output_relay_debug( DLLSPEC *spec )
output( "\t.align %d\n", get_alignment(4) );
output( ".L__wine_spec_relay_entry_point_%d:\n", i );
-
+
+ output( "\tnop\n" );
+ output( "\tnop\n" );
+ output( "\tnop\n" );
+ output( "\tnop\n" );
+ output( "\tnop\n" );
+ output( "\tnop\n" );
+ output( "\tnop\n" );
+ output( "\tnop\n" );
+
if (odp->flags & FLAG_REGISTER)
output( "\tpushl %%eax\n" );
else
--- snip ---
(rebuild)
The results seem very positive to the current state of affair.
With the "hacked" relay thunk (first 8 bytes in thunk are NOP) the following
stats are generated:
*** Note: you have to run the target with +relay to let this test work ***
kernel32 user32 gdi32 condition (cx < threshold)
--------------------------------------------------------------------
c1: 0x12 0x04 0x14 0x5F
c2: 0x02 0x00 0x04 0x3C
c3: 0x00 0x00 0x00 0x5A
So if wine could make default thunks/entry code with just enough no-op opcode
padding before jumping to real thing we can keep -fPIC.
This "feature" should be tested thoroughly, maybe some other brain damaged PE
protectors/virii might find this entry code somewhat suspicious.
Though this kind of entry code is not uncommon, Micro$oft has such kind of API
entry padding too to support "hot patching" technique (their infamous "mov edi,
edi").
Regards
--
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are watching all bug changes.
More information about the wine-bugs
mailing list