PDA

View Full Version : 4 instructions and more?


BanMe
March 9th, 2011, 16:54
Code:

PUSH FS
POP GS
PUSH GS
POP DS


Now I would expect fs to be propagated to gs and ds.. which it does under normal circumstances..But if you single step it gs is reset to 0..

normal

fs:003b
gs:0000
ds:0023


So instead of this which is what you would think would happen and in fact does under f9 execution..

fs:003b
gs:003b
ds:003b


we end up with this..under singlestepping..

fs:003b
gs:0000
ds:0000


my bad.. although both patterns 'work' on XP home and professional this can be equated to 4 or 5 pops..
from entry to execution..

Indy
March 9th, 2011, 23:39
During the conversion of trap-frame in the context(and back) of the performed corrections. See KeContextFromKframes()/KeContextToKframes():
Code:
// Set segment register contents if specified.
//

if ((ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) {

//
// Set segment registers gs, fs, es, ds.
//

//
// There's only one legal value for DS and ES, so simply set it.
// This allows KeContextFromKframes to report the real values in
// the frame. (which are junk most of the time, but sometimes useful
// for debugging.)
// Only 2 legal values for FS, let either one be set.
// Force GS to be 0 to deal with entry via SysCall and exit
// via exception.
//
// For V86 mode, the FS, GS, DS, and ES registers must be properly
// set from the supplied context.
//

if (TrapFrame->EFlags & EFLAGS_V86_MASK) {
TrapFrame->V86Fs = ContextFrame->SegFs;
TrapFrame->V86Es = ContextFrame->SegEs;
TrapFrame->V86Ds = ContextFrame->SegDs;
TrapFrame->V86Gs = ContextFrame->SegGs;
} else if (((TrapFrame->SegCs & MODE_MASK) == KernelMode)) {

//
// set up the standard selectors
//

TrapFrame->SegFs = SANITIZE_SEG(ContextFrame->SegFs, PreviousMode);
TrapFrame->SegEs = KGDT_R3_DATA | RPL_MASK;
TrapFrame->SegDs = KGDT_R3_DATA | RPL_MASK;
TrapFrame->SegGs = 0;
} else {

//
// If user mode, we simply return whatever left in context frame
// and let trap 0d handle it (if later we trap while popping the
// trap frame.) V86 mode also get handled here.
//

TrapFrame->SegFs = ContextFrame->SegFs;
TrapFrame->SegEs = ContextFrame->SegEs;
TrapFrame->SegDs = ContextFrame->SegDs;
if (TrapFrame->SegCs == (KGDT_R3_CODE | RPL_MASK)) {
TrapFrame->SegGs = 0;
} else {
TrapFrame->SegGs = ContextFrame->SegGs;
}
}
}

BanMe
March 12th, 2011, 18:26
yet debugging the anti-trace you so nicely demonstrated would require some approach to fixing it without hurting the program..

we have 3 bytes this time to contemplate.
Code:

push fs ;detect this which could also be push ds
pop gs ;store fs/ds in gs
push gs:[ecx];


So with this small bit of info, you can write a anti-trace gs bypass, in theory.

detect byte patterns
Code:

dd 0fa00fa9h;push fs pop gs
db 01eh ;push ds
dw 0fa9h;pop gs


the path might be to search for the byte code prefix 65 check the bytes before the prefix for sigs, nop them if found and either dec the prefix or nop it depending on sig found..

Indy
March 13th, 2011, 02:48
BanMe
You mean the generation of the series?

2442

2441

There are many shortcomings, but they can be solved. This optimization and the introduction of self-checks. You can modify the kernel to save the Gs.

BanMe
March 13th, 2011, 12:36
I thank you for contributing your knowledge openly..

I missed a great deal and am 'playing catch up' with 'all those RCE essays' and coding, where they clearly state not to mention to the world what you do with your time from a 'stalking' aspect... But I want my mind to be as open and 'clear' as possible..although the bait 'worked' along with reverse psychology?

Many thanks


p.s. yes gs series bypassing.

Indy
March 13th, 2011, 14:39
It is very easy to bypass in this case. Optimal use of gpe. Parsing KiTrap03() at NL = 3(KiTrap03 -> CommonDispatchException -> KiDispatchException -> KeContextToKframes). Find this construction(XP, Vista, 7):
Code:
(Cmp Reg/Mem,0x1B)
(-Line-)
(Jne L1)
(And dword ptr [Reg32 + 0x30],0)
(Jmp L2/L2)
L1:
(Mov Reg32_1,[Reg32 + 0x8C])
(Mov [Reg32 + 0x30],Reg32_1)
(L2/Jmp L2)
L2:

And patches of it, replacing the branch or modify a constant. After that Gs will be saved.

While you can manually edit in the debugger, find the function in symbols

Indy
January 19th, 2013, 14:23
BanMe
Quote:
FOR each of segment register (ES, FS, GS, and DS)
DO;
IF segment register points to data or non-conforming code segment
AND CPL > segment descriptor DPL (* stored in hidden part of segment register *)
THEN (* segment register invalid *)
SegmentSelector 0; (* null segment selector *)
FI;
OD;
END;

Code:
RPL_MASK equ 11B

mov cx,RPL_MASK
push gs
xor eax,eax
mov gs,cx
mov ax,gs
mov gs,cx
mov dx,gs
mov gs,cx
mov cx,gs
add ax,cx
add ax,dx
setz al
pop gs

.if al
int 3
.endif