News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Memory footprint / .text section writable

Started by Proto, October 29, 2007, 11:03:48 AM

Previous topic - Next topic

Proto

After trying to make my .exe smaller through linker options (merging sections etc) I noticed that there is plenty of space (in memory) after what I'm assuming is the imports table. As far as I can discern this is due to the paging system and my .text section + MZ/PE headers being loaded into the same 4kb page. Would it be advisable / safe to utilize the rest of the 4kb page in whichever way I see fit? (.text section is writeable already)

Assuming that its safe enough, what would happen if I attempted to write to [base + 1000h] (past the end of the page) ?

Tedd

Writing to the .text (code) section isn't generally a good idea, and on modern machines you run the risk of being identified as a virus - it's only old versions of windows that made the mistake of allowing it to be writeable (and newer versions just for compatibility.)
If you put any read-only data into a .const section (instead of .data) then that will be merged with the imports, which reduces the overhead quite a bit. For writeable memory, the .data? section only adds a small header into the exe, which is expanded at load time. If that's not good enough, you can always subtract some amount from the stack pointer to get a fairly big chunk and use that space. Though if you need a lot, I'd recommend allocating form the heap.
Writing to base+4k wouldn't be safe - newer machines can have 4MB pages, for a start. Secondly, you don't know what's there, it will either be a guard-page (which will cause an exception), a non-writeable/non-existent page (which will cause an exception), or a page containing needed data (which you'd be overwriting ..eventually causing an exception.)
No snowflake in an avalanche feels responsible.

Proto

There are a few code examples with .data being merged with .text (to reduce .exe size) - wouldn't that result in the entire page being writeable? (makefile has /MERGE:.data=.text). Self modifying code (I'm assuming it has non-malicious uses?) also has the .text section as writeable. All of these have potential to be misidentified as viruses?

I've been allocating from the heap, but my memory requirements changed from the size of the output file to 96h - and my .text section has from 05C0h to 0FFFh (from base) free. Is there a way to get a pointer to the beginning of the empty region without assuming only a single page is used? (and that there is room at the end of this page?)

jj2007

You can save 1024 bytes by dropping the data section, see below.

       .486
      .model flat, stdcall
      option casemap :none   ; case sensitive
      include \masm32\include\windows.inc
      include \masm32\include\user32.inc
      include \masm32\include\kernel32.inc
      includelib \masm32\lib\user32.lib
      includelib \masm32\lib\kernel32.lib
   .code
start:
   jmp   MyCodeStart

AppName   db   "No data section: ",0
MsgText   db   "Any problem?",0

MyCodeStart:
   invoke MessageBox,NULL,addr MsgText,addr AppName,MB_YESNO
   invoke ExitProcess,eax
end start


Proto

Or I could use /MERGE:.data=.text in the linker options. It saves a JMP to label (MyCodeStart). Plus theres less mess and I don't have to alter the .asm file to create a normal PE file.

Anyway, I'm not trying to make the executable smaller - I'm trying to reduce memory usage by the running program.

hutch--

Proto,

One way of further reducing the memory footprint is to use the linker options to set the stack memory smaller. If your app does not use much stack memory with stuff like recursion then set the "stack reserve - stack commit" options to a much smaller size and you will reduce memory usage by a reasonable amount.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

jj2007

Quote from: Proto on October 29, 2007, 10:29:59 PM
Or I could use /MERGE:.data=.text in the linker options. It saves a JMP to label (MyCodeStart). Plus theres less mess and I don't have to alter the .asm file to create a normal PE file.

The JMP is not even needed - just place the start: label after the data
If you need to write to this "false" data section, add /SECTION:.text,ERW to the linker option. Note all this is apparently legal - I have DEP enabled, and it works fine.

include \masm32\include\masm32rt.inc

; with data section 2560 bytes, without 1536 (i.e. 1024 less)
; .data
;    db   0

.code

AppName   db   "Test app with no data section",0
AskUser   db   "Try to write into the code section?",0
MsgText   db   "Big problem!",0

start:
   .if rv(MessageBox,NULL,addr AskUser,addr AppName,MB_YESNO or MB_DEFBUTTON2)==IDYES
     lea   edx,MsgText
     mov   eax," ooN"   ; "Big " becomes "Noo " problem
     mov   [edx],eax   ; and here it will crash if you did not set .code to ERW
   .endif
   invoke MessageBox,NULL,addr MsgText,addr AppName,MB_YESNO
   invoke ExitProcess,eax
end start

; use this line in your batch file to make the code section writable:
; \MASM32\BIN\LINK.EXE /SUBSYSTEM:WINDOWS /SECTION:.text,ERW %1.obj

Quote from: Proto on October 29, 2007, 10:29:59 PM
Anyway, I'm not trying to make the executable smaller - I'm trying to reduce memory usage by the running program.

Hutch, for a neat little MASM executable with no recursive stuff, what would be a recommended stack size? Is 1MB the standard?? Sorry for asking stupid questions, the hlp files are not very explicit...

hutch--

Unless you have an accurate measure of your stack memory usage, basically start with a small number and keep going up until it works correctly. If you know for sure that your app does nothing unusual in terms of stack usage, start with 1024 bytes and go upwards.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

jj2007

Quote from: hutch-- on October 30, 2007, 10:08:05 PM
Unless you have an accurate measure of your stack memory usage, basically start with a small number and keep going up until it works correctly. If you know for sure that your app does nothing unusual in terms of stack usage, start with 1024 bytes and go upwards.
I am confused. Here is my linker command line:

set DllOut=\DB_Circs\DB_RESRC\WEB_ETC\DbWin32.dll
\masm32\BIN\link.EXE /DLL /DEF:%1.def /SUBSYSTEM:WINDOWS /LIBPATH:\masm32\lib %1.obj /OUT:%DllOut%

I have added /STACK:nnnn with nnnn ranging from 4 bytes to 4 MB - apparently everything works, and apparently it does not make any difference on memory use shown in Task Manager. Does /STACK apply to DLLs at all? The 4 bytes value shouldn't work, since I have several multi-arg invokes.

hutch--

Your problem is using Task Manager for memory usage, use the API instead.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Proto

#10
Quote from: jj2007 on October 30, 2007, 11:05:46 PM
I have added /STACK:nnnn with nnnn ranging from 4 bytes to 4 MB - apparently everything works, and apparently it does not make any difference on memory use shown in Task Manager. Does /STACK apply to DLLs at all? The 4 bytes value shouldn't work, since I have several multi-arg invokes.

The /STACK: value is rounded up to a multiple of the page size of windows. 4 bytes -> 4kb page.

I've been using 'process explorer' to measure physical / virtual memory usage. For my app, 4kb stack size (default is 1MB I think) reduces private physical memory usage by 4K (no guard page since I've reserved only one page). Virtual size (which I'm assuming is total reserved memory) drops by 800K-900K. Thanks for the suggestion Hutch.