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. @@ -49,32 +51,20 @@ add eax,1000h-10000h mov [stack_limit],eax mov eax,[memory_setting] shl eax,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 eax,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 MEM_RESERVE push eax push 0 call [VirtualAlloc] or eax,eax jz not_enough_memory @@ -81,14 +71,16 @@ mov [memory_start],eax add eax,[memory_end] mov [memory_end],eax mov [additional_memory],eax add [additional_memory_end],eax + push memory_allocation_handler + call [SetUnhandledExceptionFilter] ret not_enough_memory: mov eax,[additional_memory_end] - shl eax,1 + lea eax,[eax*3] cmp eax,4000h jb out_of_memory jmp allocate_memory exit_program: @@ -101,10 +93,40 @@ push 0 push eax 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 .fail + mov eax,[additional_memory_end] + sub eax,edx ;don't allocate more than EAX bytes + jbe .fail + 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 + ret 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 @@ -161,10 +183,19 @@ or eax,eax jz file_error clc ret read: + push ebx edx ecx + push PAGE_READWRITE + push MEM_COMMIT + push ecx ;allocate the required number of bytes + push edx ;at this address + call [VirtualAlloc] + pop ecx edx ebx + test eax,eax + jz file_error mov ebp,ecx push 0 push bytes_count push ecx push edx