flat assembler
Message board for the users of flat assembler.

Index > Windows > Customized Segments for Windows: is it possible?

Author
Thread Post new topic Reply to topic
jbojarczuk



Joined: 21 Jun 2006
Posts: 27
jbojarczuk 20 Jan 2007, 15:09
Hi,

I wanted to try to make an entry in the LDT table, so that I would be able to make something like:

Code:
MyFunction:
    <set ES so that ES:0000000 points to SS:ESP>
    mov eax , [ES:00000004]
    


Is it possible (within a normal windows NT/2000/XP application)?

The reasoning here would be the freeing of the EBP register (register pressure) without performance penalties (Yes, I might store it inside the TIB that is at FS:0 , but I would have to load the value to a register before use)...

Thank you all
Post 20 Jan 2007, 15:09
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 20 Jan 2007, 15:15
It might be possible, but then it'd either depend on a security flaw in NT or driver code. And messing with the TIB isn't a good idea either.

Btw, "freeing the EBP register"? You're already free to use that. You problably meant freeing ESP?
Post 20 Jan 2007, 15:15
View user's profile Send private message Visit poster's website Reply with quote
jbojarczuk



Joined: 21 Jun 2006
Posts: 27
jbojarczuk 20 Jan 2007, 15:33
Actually, I would like to be able to free both...

When I talked about freeing EBP is in the case of freely messing with ESP (local dynamic allocation) without having to keep EBP to access function parameters or local variables. Say, for instance, the size of memory must be calculated with one of the parameters. Since after setting esp you would not be able to access parameter values, you would kind of be stuck, right?

Messing with TIB is a necessary thing to do, if you want to generate exception handling or per-thread global memory. Those two can only be done through TIB.

Since Exception handling structures point to local variables, you could use this guy to do what I am suggesting. The problem is the indirect memory access I am trying to avoid.

For instance,
Code:
struc TIB
{
.m_pexrExceptionList            dd ?
.m_pvStackBase                          dd ?
.m_pvStackLimit                         dd ?
        .m_pvSubSystemTib:                              ;WINNT
        .m_pvTDB:                               dw ?    ;WIN95
        .m_pvThunkSS:                   dw ?    ;WIN95

        .m_pvFiberDataOrVersion:                ;WINNT
        .m_dwUnknown                    dd ?    ;WIN95

.m_pvArbitraryUserPointer       dd ?
.m_pntbSelf                                     dd ?

        .m_dwUnknown1:                                  ;WINNT
        .m_wTIBFlags                    dw ?    ;WIN95
        .m_wWin16MutexCount             dw ?    ;WIN95

        .m_dwProcessID:                                 ;WINNT
        .m_dwDebugContext               dd ?    ;WIN95

        .m_dwThreadID:                                  ;WINNT
        .m_pCurrentPriority             dd ?    ;WIN95
        
        .m_dwUnknown2                   dd ?    ;WINNT
        .m_pvQueue                              dd ?    ;WIN95

.m_pvTLSArray                           dd ?
        
        .m_pProcess                             dd ?    ;WIN95
}

virtual at 0
TIB TIB
end virtual


MyProc:
    mov lea eax , [esp - 12]
    mov edx , [fs: TIB.m_pexrExceptionList]
    mov [esp - 8] , .ErrorHandler
    mov [esp - 12], edx
    mov [fs:TIB.m_pexrExceptionList] , eax

.... (using ESP and EBP at will)

    mov edx , [fs:TIB.m_pexrExceptionList]
    mov ecx , [edx+16]  ;<== GETTING FIRST PARAMETER

....

.ret
        ret
.ErrorHandler:
.... (Err treatment for this procedure)...
    
Post 20 Jan 2007, 15:33
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 20 Jan 2007, 16:00
jbojarczuk wrote:

Messing with TIB is a necessary thing to do, if you want to generate exception handling or per-thread global memory. Those two can only be done through TIB.

That's not "messing with", that's "using for it's intended purpose". Setting the frame pointer to something that isn't an exception frame - that's messing Smile

Apart from being "unreliable" (as in either requiring undocumented calls, depending on a security flaw, or requiring a driver), setting up a new section would incur a fair bit of overhead - ask yourself just how much you gain from having an additional register to play with.

Do you need to access function arguments in your innerloops? Smile
Post 20 Jan 2007, 16:00
View user's profile Send private message Visit poster's website Reply with quote
jbojarczuk



Joined: 21 Jun 2006
Posts: 27
jbojarczuk 20 Jan 2007, 16:32
I 'd like to experiment on setting a new section before deciding what I should be doing. I mean: we are 'playing' with assembly here, right? We are thinking of going beyond what C compilers offer us, and we are willing to walk that extra mile for it.

My goal here is to learn if this is possible. If it is, then I will analyse if it is worthwhile using.

By the way, I already tried googling it several times (several different keywords), to no avail.

Thanks for your time
Post 20 Jan 2007, 16:32
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 20 Jan 2007, 16:44
Well, try keywords like "ring0 hack idt nt" - that should give some results showing how to mess with the IDT, which is pretty analogue to the LDT. Also shows that this is a pretty dirty thing to do, so isn't worth it for mainstream code just for a tiny flick of performance, imho.

Thinking beyond compilers is one thing, but doing pretty dirty things for very little gain is another.

That said, it'll be interesting to see what you end up with, as long as you don't use it in "production code" Smile
Post 20 Jan 2007, 16:44
View user's profile Send private message Visit poster's website Reply with quote
Maverick



Joined: 07 Aug 2006
Posts: 251
Location: Citizen of the Universe
Maverick 21 Jan 2007, 10:42
jbojarczuk wrote:
(Yes, I might store it inside the TIB that is at FS:0

Not to FS:0 at all, but to FS:14H you would be entirely safe.

FS:0 = ExceptionList
FS:14 = ArbitraryUserPointer

I renamed FS:14 to ArbitraryABUserPointer :^) since I make large use of it.

_________________
Greets,
Fabio
Post 21 Jan 2007, 10:42
View user's profile Send private message Visit poster's website Reply with quote
Maverick



Joined: 07 Aug 2006
Posts: 251
Location: Citizen of the Universe
Maverick 21 Jan 2007, 10:44
f0dder wrote:
Btw, "freeing the EBP register"? You're already free to use that. You problably meant freeing ESP?

He can't free ESP, because Windows has been written (badly) and will use ESP and store stuff below it in case of an USER exception (I mean a process exception handled by user code). It would have been much better if the kernel switched the stack also for executing the [FS:0].Handler / user code. Yes, Microsoft designers suck (I don't miss any occasion, do I? Very Happy ), because if they didn't do it that way, I would directly store temporary data below ESP without even decrementing it (of course my stack does not use page guard mechanisms, but is a truly committed memory, and FS:4 and FS:8 of course reflect it).
I hope that what I meant is clear, I am in a hurry ("playing" with my Tektronix TDS-2024B), who cares about software programming when you can do hardware design!!! Very Happy

_________________
Greets,
Fabio
Post 21 Jan 2007, 10:44
View user's profile Send private message Visit poster's website Reply with quote
Maverick



Joined: 07 Aug 2006
Posts: 251
Location: Citizen of the Universe
Maverick 21 Jan 2007, 10:53
Oh, by the way, I have 5.. seconds to say 4.. that once I experimented 3.. very quickly with the idea 2.. and I recall I could at least 1.. do MOV ES,blabla without 0.. getting an exception..

LET ME DO MY ELECTRONIC DESIGN DAMMIT!!! Very Happy

Wink
Post 21 Jan 2007, 10:53
View user's profile Send private message Visit poster's website Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 21 Jan 2007, 11:28
Maverick wrote:

He can't free ESP, because Windows has been written (badly) and will use ESP and store stuff below it in case of an USER exception (I mean a process exception handled by user code).

He can use it temporarily if he doesn't generate exceptions and remember to set min/max-esp in the TIB... or are there other situations where Windows uses the stack?

IMHO it's not such a bad requirement having a valid stack in order to handle user exceptions - if you don't, your handler code most likely wouldn't be able to do anything useful.

I do think it's a bit unfortunate that exception frames have to be located on the stack, but again this is probably a sanity check - it's the de facto location, so if a exception frame pointer points outside the stack location, the rationale says that we have a corrupted stack, and need to abort.

I think this all is pretty okay for usermode exception handling... it's not perfect, but in practice it works well enough for normal stuff. And if you need to write tracing code or the like, there's always Vectored Exception Handling to (ab)use Smile

Maverick wrote:

and I recall I could at least do MOV ES,blabla without 0.. getting an exception..

Darn, it's been too long since I read the intel manuals... so I can't remember if you get an exception just by loading a selector with nonsense, or if it's only when using it to access anything. I do remember that you can load with zero without problems as long as you don't access, though.
Post 21 Jan 2007, 11:28
View user's profile Send private message Visit poster's website Reply with quote
Maverick



Joined: 07 Aug 2006
Posts: 251
Location: Citizen of the Universe
Maverick 21 Jan 2007, 14:15
f0dder wrote:
Maverick wrote:

He can't free ESP, because Windows has been written (badly) and will use ESP and store stuff below it in case of an USER exception (I mean a process exception handled by user code).

He can use it temporarily if he doesn't generate exceptions and remember to set min/max-esp in the TIB... or are there other situations where Windows uses the stack?

I haven't investigated in depth but I think there aren't.

Quote:
IMHO it's not such a bad requirement having a valid stack in order to handle user exceptions - if you don't, your handler code most likely wouldn't be able to do anything useful.

Yes, not only it's a very bad requirement, but denies my "superfast locals trick" which I even used on the Amiga. Razz While the PC CPU is perfectly capable of it, hardware wise, Windows puts itself in the middle just to bother me.
Quote:
I do think it's a bit unfortunate that exception frames have to be located on the stack, but again this is probably a sanity check - it's the de facto location, so if a exception frame pointer points outside the stack location, the rationale says that we have a corrupted stack, and need to abort.

I think it would have been better in all regards if they created a TIB member to specify the location for a temporary stack, or at least as an option (e.g. if NULL, then use the current ESP). I mean, e.g. the SEH handler's location is not taken from the stack, but from FS:0 (and *then* that points most of the times on the stack), so (although this was really necessary) it wouldn't have costed them too much brainfarting to go a bit further ahead on the concept.
ESP is a register that is not supposed to HAVE TO BE valid during exceptions, by architecture I mean, on all CPUs that have a supervisor mode or equivalent ( = protected mode on Intel).
The 80x86 architecture supports my reasoning perfectly, it's Windows that doesn't, and what advantages does this give? If I didn't tweak FS:4 and FS:8 I couldn't even switch the stack! (switching which has very useful applications)
My temporaries technique is much faster than the usual way to allocate a stack frame, copy its location to EBP, etc.. I simply directly write to ESP-xxx where I know xxx is a free storage location, and if I have to invoke a function, I simply SUB my frame size from ESP (which doesn't always happen, thus I rarely need to do anything more than *directly write* to a known ESP-xxx location). If I want to use this technique under Windows, I have to make sure no exceptions can be generated (which contraddicts the very reason why SEH exists!).
Otherwise, when I want to use some temporary stack space, I have first to SUB ESP,framesize and then to restore it. Considering that I can switch frame several times per function (in my compiler), then this is annoying [ note that I can simply subtract the biggest frame size and do it only at function prologue, the temp buffer will be big enough also for any other frames, but one thing I like to do is to "allocate" and "deallocate" arbitrary size from the stack dinamically, so also this workaround becomes uncomfortable, and may waste a lot of memory. I do every memory allocation possible on the stack, not on the heap, to fragment the latter as little as possible, let away that I don't wanna use no damn slow heap unless it makes absolutely sense to do so, I'm not a java kid!).

Quote:
I think this all is pretty okay for usermode exception handling... it's not perfect, but in practice it works well enough for normal stuff. And if you need to write tracing code or the like, there's always Vectored Exception Handling to (ab)use Smile

Maverick wrote:

and I recall I could at least do MOV ES,blabla without 0.. getting an exception..

Darn, it's been too long since I read the intel manuals... so I can't remember if you get an exception just by loading a selector with nonsense

Yes, if I recall correctly THAT generated exceptions. Wink
But if e.g. CS selector was 220H, and I MOVed 220H to ES, I got no exception and the thing even seemed to really work. Of course 220H must be a valid entry in the LDT.
Quote:
or if it's only when using it to access anything. I do remember that you can load with zero without problems as long as you don't access, though.

Yes, also 0 worked.
IIRC I tried to access some memory, but I'm not sure (it was much time ago, and anyway I got frustrated by other Windows limitations (mentioned above) who made this technique not so interesting anymore, I dedicated myself more on the Verilog hardware description language then).

Hardware development vs software programming is like making love vs petting. Very Happy

_________________
Greets,
Fabio
Post 21 Jan 2007, 14:15
View user's profile Send private message Visit poster's website Reply with quote
jbojarczuk



Joined: 21 Jun 2006
Posts: 27
jbojarczuk 21 Jan 2007, 16:17
Hi guys,

Thought you would enjoy this A LOT!!!! (I am *not* a spammer, and I haven't tried this either).

Give a look

http://vx.netlux.org/lib/vzo13.html
Post 21 Jan 2007, 16:17
View user's profile Send private message Reply with quote
System86



Joined: 15 Aug 2007
Posts: 77
System86 29 May 2008, 00:58
Documentation on how to modify the LDT using the NT native API is available on http://vx.netlux.org/lib/vzo13.html

EDIT: above link already above, did not see it when I posted this
Post 29 May 2008, 00:58
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.