flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > Segment base redefinition macro. Question.

Author
Thread Post new topic Reply to topic
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 06 Apr 2010, 23:16
Hello, everybody.
There's sometimes a need to make fasm to recalculate an offset using a different base, depending on what segment register is used. The problem would be probably more clear if one looked at the following example:
Code:
format PE GUI 4.0

include 'win32a.inc'

PAGE_SIZE  equ 4096h
TABLE_MASK equ 100b
LDT_SEL     equ 27h ;ring 3 LDT descriptor

start:
    mov dword[Seg1],12345678h
   mov dword[Seg2],87654321h

       stdcall CreateDescriptor,Seg1,0
     invoke ZwSetLdtEntries,LDT_SEL,Ecx,Edx, 0, 0, 0
     push LDT_SEL
        pop fs
      defBase fs,Seg1
     mov esi,dword [fs Seg1]

 stdcall CreateDescriptor,Seg2, 0
    mov eax,dword [ZwSetLdtEntries]
     mov eax,dword [eax + 1]     ;Service ID
     push 0
      push 0
      push 0
      push edx
    push ecx
    push LDT_SEL
        mov edx,esp
 int 2Eh                         ; ..KiIntSystemCall()
       add esp,6*4
 defBase fs,Seg2
     mov edi,dword [fs Seg2]
ret

proc CreateDescriptor,Base:DWORD,Limit:DWORD
  mov eax,[Base]
      mov edx,[Limit]
     mov ecx,eax
 and edx,0F0000h
     shr eax,16
  and ecx,0FF000000h
  and eax,0FFh
        lea edx,[eax + edx + 100h * 11110010b + 100000h * 1100b]        ; Type 001B - data, R/W.
    or edx,ecx
  mov eax,[Limit]
     mov ecx,[Base]
      and eax,0FFFFh
      shl ecx,16
  lea ecx,[ecx + eax]
; Edx:Ecx
        ret
endp

data import
    library ntdll,'ntdll.dll'

    import ntdll,\
           ZwSetLdtEntries,'ZwSetLdtEntries'
end data

align 16
Seg1  db PAGE_SIZE dup ?
Seg2  db PAGE_SIZE dup ?    

(not my code... just a simple example, a little modified by me)

This code would work if one defined defBase like this:
Code:
macro defBase reg*,base*
{
       local matched
       restore reg
 define matched -
    irps regPattern, cs ds ss es fs gs
  \{
            match =regPattern,reg
               \\{
                  restore matched
                     define matched +
            \\}
  \}
    match +,matched \{ reg equ reg:-base+ \}
    match -,matched
     \{
            display 'Error: ' # `reg # ' is not a segment register',13,10
               err
 \}
    restore matched
}
    

Disadvanteges of this macro are obvious, I think:
1) It's necessary to restore the redefined segment register (fs in this case) every time I need to access it in a non-base like manner (pop fs, for example).
2) There is a space character instead of a native colon between the base and the offset. I'd like to use a colon.

So the question is: Is there any more sophisticated way, that would eliminate these disadvantages?
Post 06 Apr 2010, 23:16
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20594
Location: In your JS exploiting you and your system
revolution 07 Apr 2010, 07:11
Is there a reason why you can't simply put:
Code:
mov edi,[fs:0]    
Or you could try:
Code:
mov edi,[fs:myValue-Seg1]
;...
virtual at Seg1
   myValue rd 1
end virtual    
Post 07 Apr 2010, 07:11
View user's profile Send private message Visit poster's website Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 07 Apr 2010, 12:59
revolution
Actually I don't really need this. For me it's only a question of possibility to do it in fasm (I know, it doesn't support inline macros). But I know people, who would appreciate such feature.
So the reason, why it would be useful, is that one may need to access really many times some memory locations from different segments with completely different bases. And it can be very annoying to write mov edi,[fs:myValue-Seg1] or even to calculate an offset by self every time one needs to access myValue. At least since it's a work of compiler to calculate offsets.
Post 07 Apr 2010, 12:59
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20594
Location: In your JS exploiting you and your system
revolution 07 Apr 2010, 13:52
This goes hand-in-hand with the segment paradigm. Segments are an ugly abomination, and this gets reflected into any assembly code that has to deal with segments.

Maybe:
Code:
struc Stuff {
  .var1 dd ?
  .var2 dd ?
}
;...
virtual at 0
  Stuff.fs Stuff
end virtual
virtual at Seg1
  Stuff.Seg1 Stuff
end virtual
;...
mov edi,[fs:Stuff.fs.var1]
mov edi,[Stuff.seg1.var1]    
Looks even worse Sad
Post 07 Apr 2010, 13:52
View user's profile Send private message Visit poster's website Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 07 Apr 2010, 15:16
revolution
Quote:
Looks even worse Sad

It really does... This is too much for absolutely no benefit.
Assume you have a big code piece, which contains many instructions accessing some different data through fs, for example. The point is to allow to load fs with a selector of another descriptor with different base, so that every memory access in this piece of code gets the same location (linear address), without making any changes in the code itself. This should be achieved by means of a single preliminary call to a macro like defBase fs,newBase.
Post 07 Apr 2010, 15:16
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-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.