Log in

View Full Version : Back to INT2E, trash SYSCALL:)


evaluator
August 1st, 2004, 07:25
>>well, 2 years, ago i found for Tsehp trikie&comfort way
>>for Single-Step tracing on XP:
>>discard "Fast System Call" 'greats' & Return back to INT2E.
>>however, until yesterday i not looked in problem about
>>m$'s Errorneous managment for SYSENTER. ok now i looked
>of course best way is back to grEat INTs.

here I quickly built DRIVER for run-time changing SYSENTER-SYSEXIT to INT2E-IRETD.
It will fail, if not find orig-INT2E handler, but it can find under active SICE;
I have only XP-original built, & if it fails on SP1-SP2, send to me NTOSKRNL.EXE.
I have not AMD(XP-ready), but i think, also should patch correctly;

USAGE:
1. start KmdManager by Four-F; (included)
2. choose driver;
3. click on "REGISTER" button; (required ADMIN privileges)
IF SUCCESS:
4. click on "RUN" button; Driver will start & exit;
If you see STATUS = SUCCESS & LAST ERROR = "The specified driver is invalid", so ALL is OK!
if you see STATUS = SUCCESS & LAST ERROR = "The request .. because of an I/O device error",
so patch not happens, because of not exact matches or already patched,
if you are trying not first time;

for be sure, what happens, look at 7FFE0300h of virtual memory;

5. finally, you can press "UNREGISTER" button.

Now you are ready for happy tracing & debugging with INT2Eh;
SICE(from DS2.7) also will mutch happy on INT2E & will display function numbers!

**
SOON: About non run-time disabling SYSENTER-SYSEXIT, or how I found..

[edit] corrected attachment in below post..

evilcry
August 1st, 2004, 08:45
Hi,
i'm new in this forum.

Intersting application, i will deeply study the source code

Have a nice day
Bye

evaluator
August 1st, 2004, 09:12
nothing big interesting I see there.. simple patcher.

Please, provide me with memory dump of address 7FFE0000h from
XP SP1,SP2;(& AMD)
I will check patterns, if they are similar with XP-orig.

doug
August 1st, 2004, 10:15
Thanks eval, very interesting indeed.

In your code, I noticed you named 'syscall': "AMD sysenter" is there any reason for that?

Here is what my system has at 7FFE0300 (Windows XP SP1, AMD Athlon XP)

Code:

7FFE0300 ; ---------------------------------------------------------------------------
7FFE0300 8B D4 mov edx, esp
7FFE0302 0F 34 sysenter
7FFE0304 C3 retn
7FFE0305 ; ---------------------------------------------------------------------------
7FFE0305 9C pushf
7FFE0306 81 0C 24 00 01 00 00 or dword ptr [esp], 100h
7FFE030D 9D popf
7FFE030E C3 retn
7FFE030F ; ---------------------------------------------------------------------------
7FFE030F 8B D4 mov edx, esp
7FFE0311 0F 05 syscall
7FFE0313 C3 retn
7FFE0314 ; ---------------------------------------------------------------------------
7FFE0314 9C pushf
7FFE0315 81 0C 24 00 01 00 00 or dword ptr [esp], 100h
7FFE031C 9D popf
7FFE031D C3 retn
7FFE031E ; ---------------------------------------------------------------------------
7FFE031E C2 08 00 retn 8
7FFE031E ; ---------------------------------------------------------------------------


Intel P4m (xp sp1)
Code:

7FFE0300 8B D4 mov edx, esp
7FFE0302 0F 34 sysenter
7FFE0304 C3 retn
7FFE0305 ; ---------------------------------------------------------------------------
7FFE0305 9C pushf
7FFE0306 81 0C 24 00 01 00 00 or dword ptr [esp], 100h
7FFE030D 9D popf
7FFE030E C3 retn
7FFE030F ; ---------------------------------------------------------------------------
7FFE030F 8B D4 mov edx, esp
7FFE0311 0F 05 syscall
7FFE0313 C3 retn
7FFE0314 ; ---------------------------------------------------------------------------
7FFE0314 9C pushf
7FFE0315 81 0C 24 00 01 00 00 or dword ptr [esp], 100h
7FFE031C 9D popf
7FFE031D C3 retn
7FFE031E ; ---------------------------------------------------------------------------
7FFE031E C2 08 00 retn 8
7FFE031E ; ---------------------------------------------------------------------------

evaluator
August 1st, 2004, 10:33
Curious
Because i merged .text with INIT, driver REalLy not loads!
I reuploaded corected zip.

doug, but in AMD docs I read 0Fh 05h is SYSENTER for amd!??

evaluator
August 1st, 2004, 10:47
nah, I just named AMD's 'SYSCALL' as AMD's SYSENTER;
(they are same functions, but another names+opc)

this is not prob, but..
so on AMD-XP at 7FFE0300h is Pentium opcode of SYSENTER!?
& this instruction is executed insteaed of AMD's SYSCALL really??

doug
August 1st, 2004, 16:12
Quote:
[Originally Posted by evaluator]
this is not prob, but..
so on AMD-XP at 7FFE0300h is Pentium opcode of SYSENTER!?
& this instruction is executed insteaed of AMD's SYSCALL really??

Yes, that's what happens here. opcode 0f 34 gets executed.

Can't really trace into with softice though.

evaluator
August 1st, 2004, 16:18
that is very okey for my driver, if same code is on AMD, so patch will same.
But anyway is interesting, why on AMD not used own "SYSCALL-SYSRET"???
(OF05h 0F07h opcodes) Any info?

later about why we can't trace into SYSENTERs terrible managment..

evaluator
August 1st, 2004, 17:02
this is little trainer on W9x for see, how easy is traicing with debugger into SYSENTER-SYSEXIT;
i built it for calculating SYSENTER-SYSEXIT speed;
15h rdtsc-cicle i have as high-speed on my 600CEL;

enjoe;

[edit], forgot.. this prog expects Pentium..

JMI
August 2nd, 2004, 04:04
Those of you following this interesting Thread will find additional discussion of these issues, including imput by some of the posters here on the exetools forum in a Thread titled: "SYSENTER hook"

http://www.exetools.com/forum/showthread.php?p=22708

Some of it is the same information, but some of it is not included in the discussion here.

Regards,

evaluator
August 2nd, 2004, 08:16
i reuploaded more correct version of SYSENTER-SYSEXIT-trainer;(for W9x)
so what speed has SYSENTER-SYSEXIT on your Pentiuses?

bilbo
August 2nd, 2004, 08:37
hi, mates,

since there is people interested in the thread, here is how I have managed to go from SYSENTER to INT 2E and vice versa.

Notes:
(a) used language is C for better reading (sorry, at least for me...)
(b) no kernel driver involved - the whole job is done by ring3
(c) platform is Windows XP (W2k has no SYSENTER stuff)
(d) I have not performed the bunch of checks which evaluator carried out... sorry: this is not a production release, just a learning tool...

Usage:
SWITCH [-INT2E | -SYSENTER]

Code:

// swap.c
// coded by bilbo on 02aug04 - compiled with M$ as "cl -W3 swap.c

#include <windows.h>
#include <stdio.h>

#pragma comment(lib, "advapi32"
#define FCHK(a) if (!(a)) { printf(#a " failed\n"; exit(0); }
#define DebugWriteMemory 9

// globals
typedef DWORD (NTAPI *PZwSystemDebugControl)(DWORD ControlCode,
PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer,
ULONG OutputBufferLength, PULONG ReturnLength);
PZwSystemDebugControl ZwSystemDebugControl;

/*
* get native entrypoint and grant debug privileges
*/
void
prepare_me(void)
{
HMODULE hModule;
HANDLE hToken;
TOKEN_PRIVILEGES tok;

// retrieve the native function ZwSystemDebugControl entrypoint
FCHK(hModule = GetModuleHandle("ntdll.dll");
FCHK((ZwSystemDebugControl = (PZwSystemDebugControl)
GetProcAddress(hModule, "ZwSystemDebugControl"));

FCHK(OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken));

tok.PrivilegeCount = 1;
tok.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

// grant debug privilege
FCHK(LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tok.Privileges[0].Luid));
FCHK(AdjustTokenPrivileges(hToken, FALSE, &tok, sizeof(tok), NULL, NULL));
}

/*
* write a buffer to kernel space
*/
void
wr(LPVOID dst, LPVOID src, DWORD len)
{
struct {
LPVOID kernel_addr;
LPVOID user_addr;
DWORD len;
} mem;

mem.kernel_addr = dst;
mem.user_addr = src;
mem.len = len;
FCHK(!ZwSystemDebugControl(DebugWriteMemory, &mem, sizeof(mem), 0, 0, 0));
}

void
main(int argc, char **argv)
{
LPVOID the_addr = (LPVOID)0xFFDF0300;

if (argc != 2) {
printf("Usage: %s -int2e to \"downgrade\" WinXP to INT 2E\n"
"\t-sysenter to \"upgrade\" it to SYSENTER\n", argv[0]);
return;
}

prepare_me();

if (!strcmp(argv[1], "-sysenter") { // restore original SYSENTER

// 8BD4 mov edx, esp
// 0F34 sysenter
// C3 ret
static BYTE SYSENTER[] = { 0x8B, 0xD4, 0x0F, 0x34, 0xC3 };

wr(the_addr, SYSENTER, sizeof(SYSENTER));

} else { // "downgrade" to INT2E

// EB03 jmp $+3 ; skip SYSENTER/RET
// 0F34 sysenter
// C3 ret
// 8D542408 lea edx, [esp+8]
// CD2E int 2eh
// C3 ret
static BYTE INT2E[] = { 0xEB, 0x03, 0x0F, 0x34, 0xC3, 0x8D, 0x54, 0x24,
0x08, 0xCD, 0x2E, 0xC3 };

wr(the_addr, INT2E, sizeof(INT2E));
}
}


Simple is beautiful, isn't it?
Best regards, bilbo

evaluator
August 2nd, 2004, 10:54
so you will overwrite code
pushf
or dword ptr [esp], 100h
popf
retn

here reterns kernel if TFlag tracing on sys enter

omega_red
August 2nd, 2004, 11:50
Do you have any docs that show working of ZwSystemDebugControl? Although I've found interesting source (search for "Copyright (C)2004 randnut@hotmail.com" on google), it'd be nice to share some knowledge

lifewire
August 2nd, 2004, 12:33
that is interesting bilbo, i didn't know that it was possible to write to kernel memory from ring3... and it quite scary too, since i see enough possibilities for abuse.

Code:

ZwSystemDebugControl performs a subset of the operations available to a kernel mode
debugger.
NTSYSAPI
NTSTATUS
NTAPI
ZwSystemDebugControl(
IN DEBUG_CONTROL_CODE ControlCode,
IN PVOID InputBuffer OPTIONAL ,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer OPTIONAL ,
IN ULONG OutputBufferLength,
OUT PULONG ReturnLength OPTIONAL
);
Parameters
ControlCode
The control code for operation to be performed. Permitted values are drawn from the
enumeration DEBUG_CONTROL_CODE .
typedef enum _DEBUG_CONTROL_CODE {
DebugGetTraceInformation =1,
DebugSetInternalBreakpoint,
DebugSetSpecialCall,
DebugClearSpecialCalls,
DebugQuerySpecialCalls,
DebugDbgBreakPoint
}DEBUG_CONTROL_CODE;
InputBuffer
Points to a caller-allocated buffer or variable that contains the data required to perform
the operation. This parameter can be null if the ControlCode parameter specifies an
operation that does not require input data.
InputBufferLength
The size in bytes of InputBuffer .
OutputBuffer
Points to a caller-allocated buffer or variable that receives the operation’s output data.
This parameter can be null if the ControlCode parameter specifies an operation that
does not produce output data.
OutputBufferLength
The size in bytes of OutputBuffer .
ReturnLength
Optionally points to a variable that receives the number of bytes actually returned to
OutputBuffer . If this information is not needed, ReturnLength may be a null pointer.


i guess i violate some copyrights here, if somebody is interested in more text you can mail me.

omega_red
August 2nd, 2004, 13:11
Quote:
[Originally Posted by lifewire]that is interesting bilbo, i didn't know that it was possible to write to kernel memory from ring3... and it quite scary too, since i see enough possibilities for abuse.

I know that it's possible by \Device\PhysicalMemory, but didn't know the SystemDebugControl way, which looks more "clean"

PS. Is your info from DDK? I think I have to spare some HD space to install msdn docs again ;]

PS2. In the source I've mentioned there are more interesting values of the control code
Code:
typedef enum _DEBUG_CONTROL_CODE {
DebugSysReadIoSpace = 14,
DebugSysWriteIoSpace = 15,
DebugSysReadMsr = 16,
DebugSysWriteMsr = 17,
DebugSysReadBusData = 18,
DebugSysWriteBusData = 19,
} DEBUG_CONTROL_CODE;

omega_red
August 2nd, 2004, 13:33
Anyway, it's not working on win2k (although ZwSystemDebugControl is present in ntdll) - I knew that XP is evil

lifewire
August 2nd, 2004, 13:55
the documentation for the api is in the book "Windows NT 2000 Native API Reference".

omega_red
August 2nd, 2004, 20:24
Great, thanks. Seems that ordering this book was also a good idea

bilbo
August 3rd, 2004, 02:08
evaluator: ??? you're setting Trace Flag, next??? obviously I'm overwriting code, I'm patching it! Have you tried the code? Does it work? That's all!

lifewire, disavowed: your doc from book and your code from "Mainsoft" refer to Win2K, and they relate to the less interesting part of the API. They are of little practical use.

omega_red: yes, WinXP is evil, and they have added the most interesting parameters to the API. Sorry you are not running it. You could always implement back inside Win2K! Here they are (found from reversing the kernel, missing in DDK docs):

Code:

DebugSysGetVersion = 7,
DebugReadMemory = 8,
DebugWriteMemory = 9,
DebugReadPhysMemory = 10,
DebugWritePhysMemory = 11,
DebugSysReadControlSpace = 12,
DebugSysWriteControlSpace = 13,
DebugSysReadIoSpace = 14,
DebugSysWriteIoSpace = 15,


Now we must infere the structures in and out to the API:

DebugSysGetVersion (7)

struct is DBGKD_GET_VERSION64, see DDK docs

DebugReadMemory (8)

look my snippet at
http://www.exetools.com/forum/showthread.php?t=4620

DebugWriteMemory (9)

look my snippet in this thread

DebugReadPhysMemory (10)
DebugWritePhysMemory (11)

they act like \Device\PhysicalMemory, which you pointed out
input struct is (names are my inventions)
Code:

typedef struct {
PVOID low_phys_addr;
PVOID high_phys_addr;
PVOID user_addr;
DWORD len;
} PHYS_MEMORY_OP;


DebugSysReadControlSpace (12)
DebugSysWriteControlSpace (13)

for KPROCESSOR_STATE structure manipulations. Input Struct is
Code:

typedef struct {
PVOID lobias; // in KPROCESSOR_STATE
PVOID hibias; // must be 0
PVOID user_addr;
DWORD len;
DWORD processor_no;
DWORD unused;
} CONTROL_STRUCT_OP;


DebugSysReadIoSpace (14)
DebugSysWriteIoSpace (15)

see my snippet at http://www.woodmann.net/forum/showthread.php?t=6056

WinXP is evil, but it is a lot more fun!
Regards, bilbo

evaluator
August 3rd, 2004, 11:37
you not understand well, what about i..
remember, you know, that if we directly will replace code on 7FFE0300,
we will have problem with past syscalls;
samely,theoretically, if there was pending traced target, then it will retern on 7FFE0305h..
this of course just theoretical fact..

so mOST safer is keeping those code also.

bilbo
August 4th, 2004, 02:21
Quote:
[Originally Posted by evaluator]
remember, you know, that if we directly will replace code on 7FFE0300,
we will have problem with past syscalls;
samely,theoretically, if there was pending traced target, then it will retern on 7FFE0305h..


That's true, past syscalls are hanging, but not at 7FFE0305, just at 7FFE0304. Let's look at the original code

Code:

7FFE0300 8BD4 MOV EDX,ESP
7FFE0302 0F34 SYSENTER
7FFE0304 C3 RET <- this must be preserved
7FFE0305 8BD4 MOV EDX,ESP
7FFE0307 0F05 SYSCALL (AMD opcode)
7FFE0309 C3 RET


It is safe to overwrite the code in red! In fact, if you put a breakpoint there, Softice will never pop-up. That's AMD code which, as we have seen so far, it is never used at the moment!

Regards, bilbo

P.S. Very interesting your MSR_AND_SYSCALLS program. I spent some delightful time disassembling it... Unfortunately I cannot try it at the moment...

bilbo
August 5th, 2004, 03:09
Tried MSR_AND_SYSCALLS on Windows 98 Pentium III 866MHz Intel:
0x15 / 0x15
The number of cycles is not depending on the clock, correct?

Regards, bilbo

evaluator
December 30th, 2004, 16:20
hi, goys!

in august i lost Internet connection, now restored;
but yet havn't normal place for PC;
today i quickly wrote this part about SYSENTER-INT2e;
check it for grammar & other errors & replay;

later i will review errors in SYSENTER management by m$;

JMI
December 30th, 2004, 23:13
evaluator, our musician friend:

Welcome back. We've missed your enduring charm and wise contributions.

Regards,

evaluator
December 31st, 2004, 10:21
JMI,

i'm not BACK & not ASS.. & here is no offtop!

remove my & your post

JMI
December 31st, 2004, 17:10
evaluator:

As frequently is the case, I'm not sure what you mean by what you wrote. I was simply trying to welcome you after a long absence.

Regards,

esther
January 1st, 2005, 23:36
He meant he posted on the wrong section.He wants you to delete the "wecome" message )just like thankyou message in exetools rofl

JMI
January 2nd, 2005, 04:41
On exetools, only those who have insufficient post count to be Members are not allowed to post "Thank You" type posts because they become excuses for trying to increase post count. However, Aaron has now activated a "Thank You" button on the threads and anyone can "thank" anyone without posting at all. It also shows in the tag with the post count how many "thank yous" one has and there is a view of those who have given the "thank you's."

And evaluator's post is not in the "wrong section." It is clearly a continuation of the prior discussion. He may have been asking me to remove my "off topic" welcome, but there is no need to do so. He is welcome back, even when he is obtuse.

Regards,

diz
January 2nd, 2005, 10:32
Quote:
[Originally Posted by JMI]"i'm not BACK & not ASS.. & here is no offtop!"

evaluator:

As frequently is the case, I'm not sure what you mean by what you wrote.


I think he said that he's not 'back'. And 'back' is what he relates to 'ass'
This might have been a words riddle, you didn't studied it long enough

JMI
January 2nd, 2005, 14:22
Actually, my own decryption was to connect the word "ASS" with my use of the phrase "wise counsel," making a play on the difference between "wise" and "wiseass." But I was not sure. Sometimes eval's jokes are more complex than I can "decrypt."

Regards,

evaluator
January 3rd, 2005, 15:55
i ripped MMIsAddressValid function (XP0) (little changed) & not understand
last check in function(@@81. Is it need? or bug? or bad rip?
explain somebody, plz

MMIsAddrVal:
mov ecx, [esp+04]
mov eax, ecx
shr eax, 14h
and eax, 0FFCh
mov eax, [eax+0C0300000h]
test al, 1
jz @@NotValid
test al, al
js @@Valid
shr ecx, 0Ah
and ecx, 3FFFFCh
sub ecx, 40000000h
mov eax, [ecx]
test al, 1
jz @@NotValid
test al, al
js @@_81

@@Valid:
mov al, 1
retn 4

@@NotValid:
xor al, al
retn 4

@@_81:
;here ECX = calculated PTE address..

and ecx, 0FFCh; (for example for @F0000000,@B0000000..etc..=0
mov eax, [ecx+0C0300000h]
and ax, 81h
cmp al, 81h
jnz @@Valid
jmp @@NotValid

Timbo
January 4th, 2005, 07:12
Well couldn't explain this but anyway
tried the backint2e system driver, changes were made, but
if i set a breakpoint (let's say GetDrivetypeA) debugger won't popup.
After i enter debugger manually i see that the breakpoint was deleted.
Without loading 'backint2e' setting breakpoints will work.

0rp
January 4th, 2005, 10:11
whats the problem with SYSCALL and singlestep?
or why is the int2e callgate 'better' than a syscall?


@evaluator you should try to get the leaked 2ksrc, that would answer your question

evaluator
January 5th, 2005, 04:07
i will never try sources; SourceLooking is against reversing!

about sysenter will continued;
but no comments about text?

Kayaker
January 6th, 2005, 00:52
Hi evaluator

That is actually explained in Bilbo's excellent analysis of the Softice PHYS command. It's a check on the Page Size (PS) and Present (P) bits of the PDE.

http://woodmann.net/forum/showpost.php?p=41341&postcount=13

Cross-reference with the Intel manual Vol 3 fig. 3.14
PS bit 7, P bit 0
81h = 1000,0001

I found a snippet from a "roll your own" MmGetPhysicalAddress that uses a similar algorithm to MmIsAddressValid which also explains it.
and ax, 81h ; PS=1 P=1 (PDE .4M Page)
cmp al, 81h

Kayk...

evaluator
January 6th, 2005, 04:01
Kayaker, i'm NOT about 81h, but ECX content! (which's PDE is there?)
force to execute that code & see..

in fact, code already is ripped & not prob to not optimise;
just interesting on strange.

Timbo
January 21st, 2005, 12:21
OT:
Well new ones on the way
0F 01 C1 vmcall

hxxp://www.heise.de/ct/04/15/024/