flat assembler
Message board for the users of flat assembler.

Index > Windows > How extend local space in 'proc'

Author
Thread Post new topic Reply to topic
marcinzabrze12



Joined: 07 Aug 2011
Posts: 61
marcinzabrze12 02 Oct 2011, 11:05
I want to extend locals space in this procedure to 32000 bytes
Code:
format PE GUI 4.0 DLL
entry DllEntryPoint        

...

; VOID ScanTree (LPSTR startdirectory, LPSTR name_filter, LPWIN32_FIND_DATA winfind, PROC_ADDRESS proced);
proc  ScanTree stdcall, startdirectory, name_filter,  winfind,  proced
locals
          handle        dd ?
          path          db 5000 dup ?
endl
macro Service
{
          lea           ebx, [path]
          mov           eax, [winfind]
          add           eax, WIN32_FIND_DATA.cFileName
          cinvoke       wsprintf, ebx, '%hs\%hs', [startdirectory], eax
          stdcall       ScanTree, ebx, [name_filter], [winfind], [proced]
}
          stdcall       ScanFolder, [startdirectory], [name_filter], [winfind], [proced]
          lea           ebx, [path]
          cinvoke       wsprintf, ebx, '%hs\*', [startdirectory]
          invoke        FindFirstFile, ebx, [winfind]
          cmp           eax, INVALID_HANDLE_VALUE
          je            .the_end
          mov           [handle], eax
          stdcall       IsSubdir, [winfind]
          test          eax, eax
          jnz           .find_next
          Service

      .find_next:
          invoke       FindNextFile, [handle], [winfind]
          test         eax, eax
          jz           @f
          stdcall      IsSubdir, [winfind]
          test         eax, eax
          jnz          .find_next
          Service
          jmp          .find_next
      @@:
          invoke       FindClose, [handle]
.the_end:
        ret
endp    
    


If i do it now program will crash
Post 02 Oct 2011, 11:05
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8358
Location: Kraków, Poland
Tomasz Grysztar 02 Oct 2011, 11:13
Use the "sp_prologue" example from the documentation. It does a stack probing for areas larger than 1000h bytes.
Post 02 Oct 2011, 11:13
View user's profile Send private message Visit poster's website Reply with quote
marcinzabrze12



Joined: 07 Aug 2011
Posts: 61
marcinzabrze12 02 Oct 2011, 15:36
my english don't let me to know it, can you show some example it will a lot simply for me. Sorry for my English I'm beginner Confused
Post 02 Oct 2011, 15:36
View user's profile Send private message Send e-mail Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4073
Location: vpcmpistri
bitRAKE 02 Oct 2011, 17:22
Simple example of dynamic stack size:
http://board.flatassembler.net/topic.php?p=31713#31713
Post 02 Oct 2011, 17:22
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8358
Location: Kraków, Poland
Tomasz Grysztar 02 Oct 2011, 18:59
marcinzabrze12 wrote:
my english don't let me to know it, can you show some example it will a lot simply for me. Sorry for my English I'm beginner Confused
Just start your source this way:
Code:
include 'win32a.inc' ; or other version

 macro sp_prologue procname,flag,parmbytes,localbytes,reglist
  { local loc
    loc = (localbytes+3) and (not 3)
    parmbase@proc equ ebp+8
    localbase@proc equ ebp-loc
    if parmbytes | localbytes
     push ebp
     mov ebp,esp
     if localbytes
      repeat localbytes shr 12
       mov byte [esp-%*4096],0
      end repeat
      sub esp,loc
     end if
    end if
    irps reg, reglist \{ push reg \} }

  prologue@proc equ sp_prologue

; here your program code    
Post 02 Oct 2011, 18:59
View user's profile Send private message Visit poster's website Reply with quote
marcinzabrze12



Joined: 07 Aug 2011
Posts: 61
marcinzabrze12 02 Oct 2011, 19:51
Tomasz like this ?
dll code:
Code:

format PE GUI 4.0 DLL
entry DllEntryPoint

PATH_LIMIT        equ   32767

include 'win32ax.inc'
section '.data' data readable writeable shareable

; Dane dla procedury ScanFolder:
        PathBuffer                 db PATH_LIMIT dup ?
        hSearchA                   dd ?

;       wskazniki referencyjne:
        cFileName                  dd ?




section '.text' code readable executable

proc DllEntryPoint   hinstDLL,  fdwReason,  lpvReserved
        mov     eax,TRUE
        ret
endp



 macro sp_prologue procname,flag,parmbytes,localbytes,reglist
  { local loc 
    loc = (localbytes+3) and (not 3) 
    parmbase@proc equ ebp+8 
    localbase@proc equ ebp-loc 
    if parmbytes | localbytes 
     push ebp 
     mov ebp,esp 
     if localbytes 
      repeat localbytes shr 12 
       mov byte [esp-%*4096],0 
      end repeat 
      sub esp,loc 
     end if 
    end if 
    irps reg, reglist \{ push reg \} } 

  prologue@proc equ sp_prologue



; VOID ScanTree (LPSTR startdirectory, LPSTR name_filter, LPWIN32_FIND_DATA winfind, PROC_ADDRESS proced);
proc  ScanTree startdirectory,  name_filter,   winfind,   proced
locals
        handle        dd ?
        path          db 3000 dup ?
endl


macro Service
{
          lea           ebx, [path]
          mov           eax, [winfind]
          add           eax, WIN32_FIND_DATA.cFileName
          cinvoke       wsprintf, ebx, '%hs\%hs', [startdirectory], eax
          stdcall       ScanTree, ebx, [name_filter], [winfind], [proced]
}
          stdcall       ScanFolder, [startdirectory], [name_filter], [winfind], [proced]
          lea           ebx, [path]
          cinvoke       wsprintf, ebx, '%hs\*', [startdirectory]
          invoke        FindFirstFile, ebx, [winfind]
          cmp           eax, INVALID_HANDLE_VALUE
          je            .the_end
          mov           [handle], eax
          stdcall       IsSubdir, [winfind]
          test          eax, eax
          jnz           .find_next
          Service

      .find_next:
          invoke       FindNextFile, [handle], [winfind]
          test         eax, eax
          jz           @f
          stdcall      IsSubdir, [winfind]
          test         eax, eax
          jnz          .find_next
          Service
          jmp          .find_next
      @@:
          invoke       FindClose, [handle]
.the_end:
        ret
endp





; ..................................................................................................
; INT ScanFolder (LPSTR folder, LPSTR name_filter, LPWIN32_FIND_DATA winfind, PROC_ADDRESS proced);
;
; opis:       Przeszukuje podany katalog w poszukiwaniu plikow o pasujacych nazwach. Jezeli trafi na
;             pasujaca nazwe wykonuje dla niej procedure ktorej adres jest podany w czwartym parametrze.
;             Jezeli podana procedura zwraca zero - funkcja wyszukuje dalej, Jezeli procedura ta zwroci
;             wartosc <> zero wtedy ScanFolder natychmiast konczy swoje dzialanie.
;
; return:
;       00    = przeszukano caly katalog
;   <>  00    = zatrzymano przez funkcje [proced]
;
; ..................................................................................................
proc ScanFolder  folder,  name_filter,  winfind,  proced
macro FileService
{
        invoke    lstrcmp, [cFileName], '.'
        test      eax, eax
        jz        .find_next
        invoke    lstrcmp, [cFileName], '..'
        test      eax, eax
        jz        .find_next



        cinvoke   wsprintf, PathBuffer, '%hs\%hs', [folder], [cFileName]
        stdcall   [proced]

        test      eax, eax
        jnz       .end_stop
}

.ustawianie_wskaznikow:
        mov       ebx, [winfind]
        add       ebx, WIN32_FIND_DATA.cFileName
        mov       [cFileName], ebx

.start:
        cinvoke   wsprintf, PathBuffer, '%hs\%hs', [folder], [name_filter]
        invoke    FindFirstFile, PathBuffer, [winfind]
        cmp       eax, INVALID_HANDLE_VALUE
        je        .end_first
        mov       [hSearchA], eax

        FileService
     .find_next:
        invoke    FindNextFile, [hSearchA], [winfind]
        test      eax, eax
        jz        .end_next
        FileService
        jmp       .find_next

.end_stop:
        inc       eax
        ret

.end_next:
        invoke    FindClose, [hSearchA]
.end_first:

        ret
endp




; &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; FUNKCJA: IsSubdir   WFD
;
; OPIS:
;       Sprawdz czy element znajdujacy sie we wskazanej
;       strukturze WIN32_FIND_DATA jest katalogiem.
;       Jezeli tak to czy jego nazwe nale|y pominac
;       podczas przeszukiwania. - nazwy '.' oraz '..'
;
; ARGUMENTY:
;       WFD     - Pointer na strukture WIN32_FIND_DATA
;
; RETURN:
;       00      - katalog
;       01      - niekatalog (lub nazwa pomijana)
;
; &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
proc IsSubdir uses ebx esi edi ebp, WFD:DWORD
pushfd
locals
        name1         db '.',0
        name2         db '..',0
endl
macro IgnoreName name
{
        lea     eax, name
        invoke  lstrcmp, ebx, eax
        test    eax, eax
        jz      .end_nie_katalog
}

;       sprawdzanie czy element w [WFD] jest katalogiem:
        mov     ebx, [WFD]
        bt      dword [ebx], 4
        jnc     .end_nie_katalog
;       sprawdzanie czy ignorowac nazwe elementu w [WFD]
        mov     ebx, [WFD]
        add     ebx, 44 ; pointer nazwy elementu do EBX

        IgnoreName      [name1]
        IgnoreName      [name2]


.end_katalog:
        xor     eax, eax
        popfd
        ret
.end_nie_katalog:
        mov     eax, 01
        popfd
        ret
endp; &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&




section '.idata' import data readable writeable

  library kernel32,'KERNEL32.DLL',\
          user32,'USER32.DLL'

include 'api\kernel32.inc'
include 'api\user32.inc'

section '.edata' export data readable
  export 'FindFile.dll',\
         ScanFolder,        'ScanFolder',\
         PathBuffer,        'PathBuffer',\
         ScanTree,          'ScanTree'

section '.reloc' fixups data discardable        
    


and here is program which use this library:
Code:
format pe gui 4.0
entry start
include 'win32ax.inc'
PATH_LIMIT        equ   32767
prefix            fix   '\\?\'
folder            fix   'd:'

section '.data' data readable writeable shareable

   startpath        db prefix, folder, 0
   name             db '*',0
   wfd              WIN32_FIND_DATA

   counter          dd 0
   buf              db 100 dup ?

   pathbuf          db PATH_LIMIT dup ?
   database         db '\list of files.rtf',0
   Hdatabase        dd ?
   odczyt           dd ?
   newline          db 13, 00

   komunikat        db 'lista plikow w lokalizacji <', folder,'>  ',0

section '.code' code readable executable
start:

        invoke  SHGetSpecialFolderPath, NULL, pathbuf, CSIDL_DESKTOP, NULL
        invoke  lstrcat, pathbuf, database
        invoke  CreateFile, pathbuf, GENERIC_READ+GENERIC_WRITE,FILE_SHARE_READ+FILE_SHARE_WRITE,\
                NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL
                .if eax = INVALID_HANDLE_VALUE
                    invoke   MessageBox, 0, 'nie udalo sie utworzyc pliku <lista plikow.txt>', 'PODSUMOWANIE', 0
                    invoke   ExitProcess, 0
                .endif

        mov     [Hdatabase], eax

        invoke  ScanTree, startpath, name, wfd, service
        invoke  CloseHandle, [Hdatabase]
        cinvoke wsprintf, buf, '%d', [counter]
        invoke  MessageBox, 0, komunikat, buf, 0
        invoke  ExitProcess,0


proc service
     inc       [counter]
     invoke    lstrlen, [PathBuffer]
     cmp       eax, MAX_PATH
     jnae      @f
               mov      ebx, eax
               push     [PathBuffer]
               pop      esi
               add      esi, 4
               invoke   lstrcat, [PathBuffer], newline
               invoke   WriteFile, [Hdatabase], esi, ebx, odczyt, NULL
     @@:
     xor       eax, eax
     ret
endp



section '.idata' import data readable
library kernel32,'kernel32.dll',user32,'user32.dll',shell32,'shell32.dll',FindFile,'FindFile.dll',gorf,'gorf32.dll'
include 'api\kernel32.inc'
include 'api\user32.inc'
include 'api\shell32.inc'
import  FindFile,\
        ScanFolder,     'ScanFolder',\
        PathBuffer,     'PathBuffer',\
        ScanTree,       'ScanTree'

                                                        
    



when i expand in proc ScanTree local buffer 'path' to 30000 bytes everything will crash. I admit that i understand nothing of sp_prolgue macro but i can't see it in work at least ...

ps. at now i'm use LocalAlloc and LocalFree to corectly work this procedure with path longer than MAX_PATH value but i think that use stack space will speed up procedure


Last edited by marcinzabrze12 on 02 Oct 2011, 20:34; edited 1 time in total
Post 02 Oct 2011, 19:51
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8358
Location: Kraków, Poland
Tomasz Grysztar 02 Oct 2011, 20:21
It crashes because you've got another problem - you do deep recursion of procedure that has such a big locals storage, and you eat up stack memory in insane amounts. The crash you get is because of the stack overflow, as you quickly run out of any stack space that Windows is able to provide.

I suggest to create a separate procedure that uses this big local buffer and which is not called recursively - then if you call it from the recursive procedure, it will only allocate this buffer one at a time.
Post 02 Oct 2011, 20:21
View user's profile Send private message Visit poster's website Reply with quote
marcinzabrze12



Joined: 07 Aug 2011
Posts: 61
marcinzabrze12 02 Oct 2011, 20:46
Yes it confirsm my assumptions. I try change method to less recursive. Any way thanks for help.
Post 02 Oct 2011, 20:46
View user's profile Send private message Send e-mail 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-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.