flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
macomics 31 Jul 2022, 17:36
|
|||
![]() |
|
f2065 31 Jul 2022, 17:43
This is a different situation. There is nothing on the link related to the bug I described. And the error codes are different.
|
|||
![]() |
|
bitRAKE 01 Aug 2022, 01:07
Not a problem on Win11, afaict.
(Relocation happens as expected.) |
|||
![]() |
|
revolution 01 Aug 2022, 08:21
Does this also affect DLLs? The relocation mechanism is the same for both.
|
|||
![]() |
|
Tomasz Grysztar 01 Aug 2022, 10:37
revolution wrote: Does this also affect DLLs? The relocation mechanism is the same for both. But ASLR not being applied usually did not mean that the image cannot be mapped at all - in fact, the trick relied on having the image properly relocated and executed, but with ASLR disabled. So perhaps the problem is not with ASLR, but with image mapping process, in which case I would suspect it might also affect DLLs. If the size of fixups causes issues, you can adjust it manually with additional IF and DW, just like we do it to enforce non-zero length of fixups for some versions of Windows. Anything you put into section marked as FIXUPS (or into DATA FIXUPS block) is appended on top of the fixups directory data. |
|||
![]() |
|
f2065 01 Aug 2022, 16:11
bitRAKE wrote: Not a problem on Win11, afaict. WinVistaSp2x64 with all updates - affected Win7sp1x32 with all updates - affected Win8.1x64 with all updates - affected Win10x32 21H2 build 19044.1865 with all updates - not affected Win11x64 21H2 build 22000.832 with all updates - not affected Windows Server 2022 Standard 21H2 build 20348.587 - not affected Tomasz Grysztar wrote: Anything you put into section marked as FIXUPS (or into DATA FIXUPS block) is appended on top of the fixups directory data. Does not work. It seems that for ASLR it is not the size of the entire section that is critical, but the size of the table in the section. I adjust the section size by adding the required amount of DW: Code: section '.reloc' data readable discardable data fixups dw 0 end data I make the section size in this way, for example 0x0000000C But it doesn't help, error on startup. In Ghidra, I see that in '.reloc' there is a link to the table, there is a real value in table+4 (for example, 0x0000000A), I fix it to 0x0000000C - and the program starts normally. |
|||
![]() |
|
f2065 01 Aug 2022, 17:04
A more informative demonstration of the work of ASLR.
What should be written in '.reloc'-section to make it work (in Win7/8.1)? Now, if the address matches with kernel32 - error 0xC0000018… Code: format PE GUI 5.01 NX at 0x10000000 ; kernel32.dll base address on my virtual computers: ; 0x7C800000 - WinXPx32 - no ASLR ; 0x76F60000 - WinVistaSp2x64 with all updates - affected ; 0x75DA0000 - Win7sp1x32 with all updates - affected ; 0x771A0000 - Win8.1x64 with all updates - affected ; 0x75AF0000 - Win10x32 21H2 build 19044.1865 with all updates - not affected ; 0x76630000 - Win11x64 21H2 build 22000.832 with all updates - not affected ; 0x75BD0000 - Windows Server 2022 Standard 21H2 build 20348.587 with all updates - not affected entry EntryTestASLR32 include '%fasm%\include\win32a.inc' section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL',\ shlwapi,'SHLWAPI.DLL' import user32,\ MessageBoxA,'MessageBoxA' import kernel32,\ GetModuleHandleA,'GetModuleHandleA',\ GetModuleFileNameW,'GetModuleFileNameW',\ CreateFileW,'CreateFileW',\ GetFileSizeEx,'GetFileSizeEx',\ LocalAlloc,'LocalAlloc',\ LocalFree,'LocalFree',\ ReadFile,'ReadFile',\ CloseHandle,'CloseHandle',\ ExitProcess,'ExitProcess' import shlwapi,\ wnsprintfA,'wnsprintfA' section '.text' code readable executable EntryTestASLR32: ; enable/disable this line for change '.reloc' size mov eax, this_label_for_align_reloc ; enable - reloc size invalid ; disable - reloc size normal invoke GetModuleHandleA, t_kernel32 mov [kernel32_address], eax invoke GetModuleHandleA, 0 mov [current_address_MEM], eax stdcall get_addr_from_PE_header mov [current_address_PE], eax mov eax, [current_address_PE] test eax, eax jz aslr_fail cmp eax, [current_address_MEM] je aslr_fail cinvoke wnsprintfA, text_buffer, size_text_buffer, t_mask_OK, [kernel32_address], [current_address_MEM], [current_address_PE] jmp view_res aslr_fail: cinvoke wnsprintfA, text_buffer, size_text_buffer, t_mask_ERR, [kernel32_address], [current_address_MEM], [current_address_PE], [kernel32_address] view_res: invoke MessageBoxA, 0, text_buffer, mb_header, 0 invoke ExitProcess, 0 proc get_addr_from_PE_header locals dqFileSize dq ? dwTemp dd ? filename dw MAX_PATH dup (?) endl push edi push esi push ebx lea edx, [filename] invoke GetModuleFileNameW, 0, edx, MAX_PATH lea ecx, [filename] invoke CreateFileW, ecx, GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 cmp eax, INVALID_HANDLE_VALUE je .err0 mov ebx, eax ; hFile lea esi, [dqFileSize] mov dword [esi], 0 mov dword [esi+4], 0 invoke GetFileSizeEx, ebx, esi test eax, eax jz .err0 cmp dword [esi+4], 0 jnz .err0 mov esi, [esi+0] test esi, esi jle .err0 invoke LocalAlloc, LPTR, esi test eax, eax jz .err0 mov edi, eax lea edx, [dwTemp] invoke ReadFile, ebx, edi, esi, edx, 0 test eax, eax jz .err0 invoke CloseHandle, ebx lea ecx, [edi + 0x3C] ; IMAGE_DOS_HEADER.e_lfanew mov ecx, [ecx] add ecx, edi lea ecx, [ecx + 0x34] ; IMAGE_NT_HEADERS32.OptionalHeader.ImageBase mov esi, [ecx] invoke LocalFree, edi mov eax, esi jmp .return .err0: xor eax, eax .return: pop ebx pop esi pop edi ret endp section '.data' data readable writeable kernel32_address dd ? current_address_MEM dd ? current_address_PE dd ? this_label_for_align_reloc dd ? t_kernel32 db "kernel32.dll",0 mb_header db "ASLR test2",0 t_mask_OK db "kernel32 address in memory: 0x%08X",13,10,\ "current process address in memory: 0x%08X",13,10,\ "base address in the PE-header of the current process: 0x%08X",13,10,13,10,\ "ASLR test result: OK",0 t_mask_ERR db "kernel32 address in memory: 0x%08X",13,10,\ "current process address in memory: 0x%08X",13,10,\ "base address in the PE-header of the current process: 0x%08X",13,10,13,10,\ "ASLR test result: Change the address in the first line of the source to '0x%08X' and rebuild the program.",0 size_text_buffer = 2048 text_buffer rb size_text_buffer section '.reloc' data readable discardable fixups |
|||
![]() |
|
Tomasz Grysztar 01 Aug 2022, 18:21
I think it is a mistake to frame it as an ASLR-related issue, when the actual problem is that fixups fail to be applied when relocation is necessary because of conflicting base address. These are separate things, and failing ASLR normally does not prevent the program from starting. If the base of image is already reserved/used for other purpose, then relocation is always needed, and this applies to all versions of Windows since the PE format was introduced, way before ASLR. See my video about Win32s for example.
f2065 wrote: In Ghidra, I see that in '.reloc' there is a link to the table, there is a real value in table+4 (for example, 0x0000000A), I fix it to 0x0000000C - and the program starts normally. The PE specification states that each relocation block needs to start on a 32-bit boundary, which is not the same as each block needing to have an aligned size, but in practice this only makes a difference in the final block. The implementation in fasm 1 took the specification quite literally - not aligning the length of the final block. But I'm pretty sure fasmg's PE formatter does align all the fixups block sizes, including the final one. If you move to fasmg, the issue may no longer be a concern. The formatter in fasm 1 is mostly preserved in a backward-compatible state, while with fasmg I could take a more liberal approach, considering that the formatter that is in form of an .INC file can be easily adjusted. |
|||
![]() |
|
f2065 01 Aug 2022, 22:37
Tomasz Grysztar wrote: The PE specification states that each relocation block needs to start on a 32-bit boundary, which is not the same as each block needing to have an aligned size, but in practice this only makes a difference in the final block. The implementation in fasm 1 took the specification quite literally - not aligning the length of the final block. However, for Windows 7/8.1 it is necessary that the size of this data be a multiple of 4 (and also the minimum section size is 8). There is no bug in fasmg, it makes the block size up to 4 - I checked by adding and removing lines that affect the number of relocations. But switching to fasmg is too complicated, and for example it is not clear how to make a .fas file (and whether it will be compatible?) - there is no -s switch ... Is it possible to somehow solve this problem (with the size) in fasm1? Add some new argument for size alignment? So far I have come up with only such a solution, but it's not right: Code: section '.reloc' data readable discardable fixups if (($ - $$) mod 4) > 0 display "invalid fixup size!",13,10 err end if |
|||
![]() |
|
revolution 02 Aug 2022, 05:42
If fasm is updated with a fix what is a good way to pad the reloc section?
|
|||
![]() |
|
I 02 Aug 2022, 06:37
If the upper 4 bits of the word are zero it's recognized as padding, no?
https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#the-reloc-section-image-only Quote: IMAGE_REL_BASED_ABSOLUTE | 0 | The base relocation is skipped. This type can be used to pad a block. |
|||
![]() |
|
Tomasz Grysztar 02 Aug 2022, 07:20
revolution wrote: If fasm is updated with a fix what is a good way to pad the reloc section? |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.