Index: SOURCE/WIN32/FASM.ASM ================================================================== --- SOURCE/WIN32/FASM.ASM +++ SOURCE/WIN32/FASM.ASM @@ -1,11 +1,11 @@ ; flat assembler interface for Win32 ; Copyright (c) 1999-2015, Tomasz Grysztar. ; All rights reserved. - format PE console + format PE console large section '.text' code readable executable start: @@ -380,11 +380,11 @@ GetStdHandle dd rva _GetStdHandle VirtualAlloc dd rva _VirtualAlloc VirtualFree dd rva _VirtualFree GetTickCount dd rva _GetTickCount GetSystemTime dd rva _GetSystemTime - GlobalMemoryStatus dd rva _GlobalMemoryStatus + SetUnhandledExceptionFilter dd rva _SetUnhandledExceptionFilter dd 0 kernel_name db 'KERNEL32.DLL',0 _ExitProcess dw 0 @@ -411,9 +411,9 @@ db 'VirtualFree',0 _GetTickCount dw 0 db 'GetTickCount',0 _GetSystemTime dw 0 db 'GetSystemTime',0 - _GlobalMemoryStatus dw 0 - db 'GlobalMemoryStatus',0 + _SetUnhandledExceptionFilter dw 0 + db 'SetUnhandledExceptionFilter',0 section '.reloc' fixups data readable discardable Index: SOURCE/WIN32/SYSTEM.INC ================================================================== --- SOURCE/WIN32/SYSTEM.INC +++ SOURCE/WIN32/SYSTEM.INC @@ -1,5 +1,7 @@ +MEMORY_ALLOCATION_BLOCK_SIZE = 1 shl 16 ;64kB. Higher numbers reduce the number of calls to the allocator. A value of 1 will allocate just the page where the memory is accessed +MEMORY_ALLOCATION_MAX_SIZE = 0x7ffc0000 ;Windows fails all calls that try to allocate more than this ; flat assembler interface for Win32 ; Copyright (c) 1999-2015, Tomasz Grysztar. ; All rights reserved. @@ -46,52 +48,58 @@ mov [memory_start],eax mov eax,esp and eax,not 0FFFh add eax,1000h-10000h mov [stack_limit],eax - mov eax,[memory_setting] - shl eax,10 + mov ebx,[memory_setting] + shl ebx,10 jnz allocate_memory - push buffer - call [GlobalMemoryStatus] - mov eax,dword [buffer+20] - mov edx,dword [buffer+12] - cmp eax,0 - jl large_memory - cmp edx,0 - jl large_memory - shr eax,2 - add eax,edx - jmp allocate_memory - large_memory: - mov eax,80000000h + mov ebx,MEMORY_ALLOCATION_MAX_SIZE allocate_memory: - mov edx,eax - shr edx,2 - mov ecx,eax - sub ecx,edx - mov [memory_end],ecx - mov [additional_memory_end],edx push PAGE_READWRITE - push MEM_COMMIT - push eax + push MEM_RESERVE + push ebx push 0 - call [VirtualAlloc] - or eax,eax + call [VirtualAlloc] ;allocate the main section + test eax,eax jz not_enough_memory mov [memory_start],eax - add eax,[memory_end] + add eax,ebx + mov [memory_end],eax + cmp [memory_setting],0 + jnz .use_single_section + mov eax,ebx + shr eax,1 + push PAGE_READWRITE + push MEM_RESERVE + push eax + push 0 + call [VirtualAlloc] ;allocate the additional section + test eax,eax + jz .use_single_section + mov [additional_memory],eax + shr ebx,1 + add eax,ebx + mov [additional_memory_end],eax + .memory_okay: + push memory_allocation_handler + call [SetUnhandledExceptionFilter] + ret + .use_single_section: + mov eax,[memory_end] + mov [additional_memory_end],eax + shr ebx,2 + sub eax,ebx mov [memory_end],eax mov [additional_memory],eax - add [additional_memory_end],eax - ret + jmp .memory_okay not_enough_memory: - mov eax,[additional_memory_end] - shl eax,1 - cmp eax,4000h - jb out_of_memory - jmp allocate_memory + shr ebx,2 + lea ebx,[ebx*3] + cmp ebx,4000h + jae allocate_memory + jmp out_of_memory exit_program: movzx eax,al push eax mov eax,[memory_start] @@ -99,12 +107,53 @@ jz do_exit push MEM_RELEASE push 0 push eax call [VirtualFree] + push MEM_RELEASE + push 0 + push [additional_memory] + call [VirtualFree] do_exit: call [ExitProcess] + +memory_allocation_handler: + mov eax,[esp+4] ;get pointer to exception information + mov ecx,[eax] ;EXCEPTION_POINTERS.ExceptionRecord + mov edx,[ecx] ;EXCEPTION_RECORD.ExceptionCode + cmp edx,0xc0000005 ;EXCEPTION_ACCESS_VIOLATION + jnz .fail + mov edx,[ecx+24] ;EXCEPTION_RECORD.ExceptionAddress + cmp edx,[memory_start] + jb .check_additional + mov eax,[memory_end] + sub eax,edx ;don't allocate more than EAX bytes + ja .allocate + .check_additional: + cmp edx,[additional_memory] + jb .fail + mov eax,[additional_memory_end] + sub eax,edx ;don't allocate more than EAX bytes + jbe .fail + .allocate: + mov ecx,MEMORY_ALLOCATION_BLOCK_SIZE + cmp eax,ecx + jbe .allocation_size_defined + mov eax,ecx ;don't allocate more than ECX bytes + .allocation_size_defined: + push PAGE_READWRITE + push MEM_COMMIT + push eax ;allocate this many bytes + push edx ;at this address + call [VirtualAlloc] + test eax,eax + jz out_of_memory + mov eax,-1 ;EXCEPTION_CONTINUE_EXECUTION + retn 4 + .fail: ;some other exception happened + mov eax,0 ;EXCEPTION_CONTINUE_SEARCH + retn 4 get_environment_variable: mov ecx,[memory_end] sub ecx,edi cmp ecx,4000h @@ -162,13 +211,22 @@ jz file_error clc ret read: mov ebp,ecx + push edx + push PAGE_READWRITE + push MEM_COMMIT + push ecx ;allocate the required number of bytes + push edx ;at this address + call [VirtualAlloc] + pop edx + test eax,eax + jz out_of_memory push 0 push bytes_count - push ecx + push ebp push edx push ebx call [ReadFile] or eax,eax jz file_error