flat assembler
Message board for the users of flat assembler.

Index > Windows > format PE64 GUI 4.0 DLL needs relocations with FASM 1.70

Author
Thread Post new topic Reply to topic
pzimm



Joined: 09 Aug 2012
Posts: 2
pzimm 09 Aug 2012, 14:52
After upgrading from FASM version 1.68 to version 1.70.03 I have observed that DLLs created in PE64 format are no longer loaded properly (at least with Windows Vista Ultimate 64 Bit). I have figured out that statement
Code:
        mov     dword [edx+16h],20B002Fh; flags and magic value     
    

at line 1043 of include FORMATS.INC has been changed. The LSB of 20B0002Fh indicates now that the image can only be loaded at its preferred base address if relocations are missing. In former versions (e.g. 1.68 ) the corresponding statement was
Code:
        mov     dword [edx+16h],20B002Eh; flags and magic value 
    

with the LSB set to zero.

You may reproduce the problem if you compile the following DLL
Code:
format PE64 GUI 4.0 DLL

entry   DllMain

section '.text' code readable executable

                        align   16

DllMain:                mov     eax,1
                        ret

                        align   16

myfun:                  mov     rax, rcx
                        inc     rax
                        ret


section '.edata' export data readable

                        dd      0                               ; Export Flags
                        dd      0x50225E51                      ; Time/Date Stamp
                        dw      0                               ; Major Version
                        dw      0                               ; Minor Version
                        dd      RVA _DllName                    ; Name RVA
                        dd      1                               ; Ordinal Base
                        dd      1                               ; Address Table Entries
                        dd      1                               ; Number of Name Pointers
                        dd      RVA ExportAddressTable          ; Export Address Table RVA
                        dd      RVA ExportNamePointerTable      ;
                        dd      RVA ExportOrdinalTable          ;

ExportAddressTable:
                        dd      RVA myfun

ExportNamePointerTable:
                        dd      RVA _myfun

ExportOrdinalTable:
                        dw      0

_DllName                db      'LIBTEST.DLL',0

_myfun                  db      'myfun',0 
    

as LIBTEST.DLL and try to use it with the following executable:
Code:
format PE64 console 4.0

entry   main

section '.text' code readable executable

main:                   enter   32, 0
                        mov     ecx, 4711
                        call    [myfun]
                        leave
                        ret

section '.idata' import data readable writeable

                        dd 0,0,0,RVA _libtest_dllname, RVA _libtest_table
                        dd 0,0,0,0,0

_libtest_table:
myfun                   dq RVA _myfun, 0

_myfun                  dw 0
                        db 'myfun',0

_libtest_dllname        db 'LIBTEST.DLL',0 
    


This example works with version 1.68 but does not work with version 1.70.03. Changing the line in FORMATS.INC back to its original state and recompiling fasmw.exe makes the example working again with version 1.70.03.

Kind regards,
Peter
Post 09 Aug 2012, 14:52
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 09 Aug 2012, 15:22
It was a bugfix. When you don't put fixups into your image, fasm assembles it with absolute (not relocatable) addresses, and thus it cannot know whether this image can be relocatable or not. The IMAGE_FILE_RELOCS_STRIPPED is thus set in such case, to let system know that the image may not be safe to relocate. Because this DLL shares the same address with the program that tries to load it, and the DLL image cannot be relocated, loader fails.
To see that this is the only reason you can change the first line of DLL to this one:
Code:
format PE64 GUI 4.0 DLL at 1000000h    
and see that loading succeeds in such case.

But the proper solution is to put relocations somewhere in the DLL image, like this:
Code:
data fixups
end data    
Even if they will end up empty, it is important because fasm then assembles image with relocatable addresses and can safely reset the IMAGE_FILE_RELOCS_STRIPPED flag.
Post 09 Aug 2012, 15:22
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 09 Aug 2012, 15:28
PS In case you don't know what does it mean that fasm assembles with absolute addresses, I will show it on a simple example. When fasm uses absolute values for labels (as it does when you don't put fixups into your image) you are allowed to do things like:
Code:
        mov     rax,(DllMain shr 3) xor 0xABCD    
While with relocatable labels the above line is not allowed and will not get assembled.
And this is because of allowing such things that fasm is not able to guarantee that the image will be safely relocatable and thus sets the IMAGE_FILE_RELOCS_STRIPPED flag.
Post 09 Aug 2012, 15:28
View user's profile Send private message Visit poster's website Reply with quote
pzimm



Joined: 09 Aug 2012
Posts: 2
pzimm 10 Aug 2012, 12:50
Hi Tomasz,

Thanks for your quick response. I have understood the reason setting IMAGE_FILE_RELOCS_STRIPPED if the image does not contain fixups. But how can I assemble and successfully load the following code

Code:
format PE64 GUI 4.0 DLL at 400000h

entry   DllMain

section '.text' code readable executable

                        align   16

DllMain:                mov     eax,1
                        ret

                        align   16

myfun:                  mov     rax, rcx
                        add     rax, [rip-.next+.constant]
.next:                  ret

                        align   8
.constant               dq      0x7621

section '.edata' export data readable

                        dd      0                               ; Export Flags
                        dd      %t                              ; Time/Date Stamp
                        dw      0                               ; Major Version
                        dw      0                               ; Minor Version
                        dd      RVA _DllName                    ; Name RVA
                        dd      1                               ; Ordinal Base
                        dd      1                               ; Address Table Entries
                        dd      1                               ; Number of Name Pointers
                        dd      RVA ExportAddressTable          ; Export Address Table RVA
                        dd      RVA ExportNamePointerTable      ;
                        dd      RVA ExportOrdinalTable          ;

ExportAddressTable:
                        dd      RVA myfun

ExportNamePointerTable:
                        dd      RVA _myfun

ExportOrdinalTable:
                         dw      0

_DllName                db      'LIBTEST.DLL',0

_myfun                  db      'myfun',0 
    


The code is completely relocatable, but I cannot assemble it with fixups (-> "Error: Invalid use of symbol."). Without fixups it can't be loaded due to IMAGE_FILE_RELOCS_STRIPPED set and the conflicting base address. If I clear bit IMAGE_FILE_RELOCS_STRIPPED within the image (i.e. change byte 0x2fh to 0x2e at offset 0x96) it will be loaded and executed successfully.

Kind regards,
Peter
Post 10 Aug 2012, 12:50
View user's profile Send private message Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 10 Aug 2012, 20:41
pzimm
I actually think, the compiler should resolve this situation, but until then you could replace
Code:
add     rax, [rip-.next+.constant]    

with
Code:
add     rax, [rip+.constant-.next]    
Post 10 Aug 2012, 20:41
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 26 Sep 2012, 12:51
l_inc wrote:
pzimm
I actually think, the compiler should resolve this situation, (...)
The 1.71.02 release includes this improvement.
Post 26 Sep 2012, 12:51
View user's profile Send private message Visit poster's website 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.