Hi
I create with VirtualAlloc Palce for the pszText
and after working with the text use i VirtualFree
How i can test if the memory free?
invoke GetWindowTextLength, hWnd
.if eax > 0
inc eax
mov dwBufferSize, eax
invoke VirtualAlloc,0,eax,MEM_COMMIT,PAGE_EXECUTE_READWRITE
push ebx
mov pszText, eax
lea ebx,[eax]
invoke GetWindowText,hWnd,ebx, dwBufferSize
.if eax
; Working with text.............
invoke VirtualFree,dwBufferSize,ebx,MEM_DECOMMIT
.endif
QuoteVirtualFree...
Return Value
If the function succeeds, the return value is nonzero.
If the function fails, the return value is 0 (zero). To get extended error information, call GetLastError.
that's the easy way :P
The return value is in the EAX register, as others pointed out to me. You probably know that, but anyway... just in case.
Thanks for your post
Yes i have already read this
invoke VirtualFree,dwBufferSize,ebx,MEM_DECOMMIT
.if eax==0
;True
.elseif eax!=0
;False
.endif
How i can test it if this really free can i this see in Ollydbg?
You have that the wrong way round ragdog
invoke VirtualFree,dwBufferSize,ebx,MEM_DECOMMIT
.if eax!=0
;True
;The memory is free
.elseif eax==0
;False
;The memory is not free
.endif
Reading further:
MEM_DECOMMIT
0x4000 Decommits the specified region of committed pages. After the operation, the pages are in the reserved state.
The function does not fail if you attempt to decommit an uncommitted page. This means that you can decommit a range of pages without first determining the current commitment state.
I dont use the function myself but I would imagine this function would help you:
VirtualQuery
http://msdn.microsoft.com/en-us/library/aa366902(v=VS.85).aspx
Quote from: ragdog on July 11, 2010, 05:27:13 PM
How i can test it if this really free can i this see in Ollydbg?
The 'memory map' window in Olly will show you what memory is alloacted to your process. Monitor it before and after the call, and you should see it the range dissapear. As far as testing to see if it's there programatically, you need to either walk the VAD tree yourself (non-trivial), or just try and access it to see if your program crashes (or, more likely, set up an exception handler to deal with the success).
-r
well - the only way i can think of testing it is free (besides the success of the Free call), is to see if it can be re-allocated :P
that seems rather silly, because the OS may not allocate that block unless you request it allocates all available memory
note: after you free a block, you may still be able to read and write to that block without generating an exception
of course, that sounds like a good way to make bad things happen - lol
ahhh - redskull is on to something, there :P
there must be an easy API function to use that returns memory blocks allocated to the current process
Quote from: dedndave on July 11, 2010, 05:41:39 PM
note: after you free a block, you may still be able to read and write to that block without generating an exception
Thats interesting, dedndave. What conditions can cause this behavior?
-r
try it out :bg
i tried it once, expecting to generate the old "c0000005" error, but the program kept on trucking - lol
Try IsBadReadPtr(). That might work, though I don't understand why the return value of VirtualFree() isn't sufficient.
Ok thanks :U
This was my Mistake ::)
lol - let's call it microsoft's mistake, instead
one would naturally expect the exception error
I have trouble with this virtualfree
Why Free this not the memory
.data?
nSize dd ?
pszMem dd ?
.code
push hWnd
call AllocateEditBuffer
.if (pszMem != NULL)
invoke MessageBox,0,addr pszMem,0,MB_OK
call DeAllocateMem
.endif
AllocateEditBuffer Proc uses ebx hWnd:HWND
invoke GetWindowTextLength, hWnd
.if (eax>0)
inc eax
mov nSize, eax
invoke VirtualAlloc,0,eax,MEM_COMMIT,PAGE_READWRITE
.if (eax != NULL)
mov pszMem,eax
invoke GetWindowText,hWnd, pszMem,nSize
.if (pszMem != NULL)
ret
.endif
.endif
.endif
ret
AllocateEditBuffer endp
DeAllocateMem proc
invoke VirtualFree,pszMem, nSize,MEM_DECOMMIT
.if (eax!=0)
invoke MessageBox,0,CTEXT ("The memory is free"),0,MB_OK
.else
invoke MessageBox,0,CTEXT ("The memory is not free"),0,MB_OK
.endif
ret
DeAllocateMem endp
Allocate the memory works fine only not this Free Mem (VirtualFree)
MEM_DECOMMIT doesn't "free" the memory; it leaves the address space reserved to your program, but with no backing RAM (and/or pagefile space) behind it. So, you must specificy how you define "failure" for this snippit (VirtualFree fails, memory still visible in Olly, can still read and write to it, etc). By decomiting only, the addressess appear to be there, but don't actually exist.
-r
If i use MEM_DECOMMIT or MEM_RELEASE have i ervery "The memory is not free" result
a hint: use MEM_COMMIT and MEM_RESERVE together, if MEM_RESERVE wasn't used previously. Then MEM_RELEASE will do its job fine.
Thanks I comming not further with it
I have change to
invoke VirtualAlloc,0,eax,MEM_COMMIT or MEM_RESERVE,PAGE_READWRITE
mov pszMem,eax
...
..
invoke VirtualFree, pszMem,nSize,MEM_RELEASE
.if (eax!=0)
invoke MessageBox,0,CTEXT ("The memory is free"),0,MB_OK
.else
invoke MessageBox,0,CTEXT ("The memory is not free"),0,MB_OK
.endif
With same result :red
Can you post me an example?
Quote from: ragdog on July 18, 2010, 06:36:31 PM
invoke VirtualFree, pszMem,nSize,MEM_RELEASE
If you specify this value, dwSize must be 0 (zero)
invoke VirtualAlloc,0,8192,MEM_COMMIT or MEM_RESERVE,PAGE_READWRITE
mov pszMem,eax
invoke VirtualFree, pszMem,0,MEM_RELEASE
print str$(eax)
inkey
eax prints '1'
Thanks
Now have i found this bug i have no idea why and how i can solve it
If the pszMem filled from GetWindowText cannot free it
invoke GetWindowText,hWnd,addr pszMem,nSize
I have try bevore i use VirtualFree ,use RtlZeroMemory without good result
I dont use windows controls but surely this would work?
invoke VirtualAlloc,0,8192,MEM_COMMIT or MEM_RESERVE,PAGE_READWRITE
mov pszMem,eax
invoke GetWindowText,hWnd,pszMem,nSize <---- Note not 'ADDR pszMem'
invoke VirtualFree, pszMem,0,MEM_RELEASE
Where nSize is the number of characters you want to copy
Quote
invoke GetWindowText,hWnd,pszMem,nSize <---- Note not 'ADDR pszMem'
Without use addr works this VirtualFree
But I cannot get the text from edit control :wink
Gives a other way with other alloc apis?
The functions all appear to work the way they are documented to work.
;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
.data
pMem dd 0
.code
;==============================================================================
ShowState proc ptrMem:DWORD
LOCAL mbi:MEMORY_BASIC_INFORMATION
invoke VirtualQuery, ptrMem, ADDR mbi, SIZEOF mbi
SWITCH mbi.State
CASE MEM_COMMIT
print "MEM_COMMIT",13,10
CASE MEM_FREE
print "MEM_FREE",13,10
CASE MEM_RESERVE
print "MEM_RESERVE",13,10
ENDSW
ret
ShowState endp
;==============================================================================
start:
;==============================================================================
invoke ShowState, pMem
invoke VirtualAlloc, NULL, 1024, MEM_COMMIT, PAGE_READWRITE
mov pMem, eax
.IF eax == 0
print LastError$(),13,10
.ENDIF
invoke ShowState, pMem
invoke VirtualFree, pMem, 0, MEM_RELEASE
.IF eax == 0
print LastError$(),13,10
.ENDIF
invoke ShowState, pMem
invoke VirtualAlloc, NULL, 1024, MEM_RESERVE, PAGE_READWRITE
mov pMem, eax
.IF eax == 0
print LastError$(),13,10
.ENDIF
invoke ShowState, pMem
invoke VirtualFree, pMem, 0, MEM_DECOMMIT
.IF eax == 0
print LastError$(),13,10
.ENDIF
invoke ShowState, pMem
invoke VirtualFree, pMem, 0, MEM_RELEASE
.IF eax == 0
print LastError$(),13,10
.ENDIF
invoke ShowState, pMem
inkey "Press any key to exit..."
exit
;==============================================================================
end start
typedef struct _MEMORY_BASIC_INFORMATION {
PVOID BaseAddress;
PVOID AllocationBase;
DWORD AllocationProtect;
SIZE_T RegionSize;
DWORD State;
DWORD Protect;
DWORD Type;
} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
MEM_FREE
MEM_COMMIT
MEM_FREE
MEM_RESERVE
MEM_RESERVE
MEM_FREE
And the same for this code:
;==============================================================================
; Build as console app so print can display.
;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
IDC_EDIT equ 101
IDC_BTNU equ 102
IDC_BTNL equ 103
;==============================================================================
.data
hInstance dd 0
hwndEdit dd 0
.code
;==============================================================================
DlgProc proc hwndDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
LOCAL pMem:DWORD, tLength:DWORD
SWITCH uMsg
CASE WM_INITDIALOG
invoke GetDlgItem, hwndDlg, IDC_EDIT
mov hwndEdit, eax
CASE WM_COMMAND
SWITCH wParam
CASE IDC_BTNU
invoke GetWindowTextLength, hwndEdit
inc eax
mov tLength, eax
print str$(eax),13,10
invoke VirtualAlloc, NULL, eax, MEM_COMMIT, PAGE_READWRITE
mov pMem, eax
print hex$(eax),13,10
invoke GetWindowText, hwndEdit, pMem, tLength
print str$(eax),13,10
invoke crt__strupr, pMem
print hex$(eax),13,10
invoke SetWindowText, hwndEdit, pMem
print str$(eax),13,10
invoke VirtualFree, pMem, 0, MEM_RELEASE
print str$(eax),13,10,13,10
CASE IDC_BTNL
invoke GetWindowTextLength, hwndEdit
inc eax
mov tLength, eax
print str$(eax),13,10
invoke VirtualAlloc, NULL, eax, MEM_COMMIT, PAGE_READWRITE
mov pMem, eax
print hex$(eax),13,10
invoke GetWindowText, hwndEdit, pMem, tLength
print str$(eax),13,10
invoke crt__strlwr, pMem
print hex$(eax),13,10
invoke SetWindowText, hwndEdit, pMem
print str$(eax),13,10
invoke VirtualFree, pMem, 0, MEM_RELEASE
print str$(eax),13,10,13,10
CASE IDCANCEL
invoke EndDialog, hwndDlg, 0
ENDSW
CASE WM_CLOSE
invoke EndDialog, hwndDlg, 0
ENDSW
xor eax, eax
ret
DlgProc endp
;==============================================================================
start:
;==============================================================================
invoke GetModuleHandle, NULL
mov hInstance, eax
Dialog "Test", \
"MS Sans Serif",10, \
WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \
3,0,0,130,110,1024
DlgEdit WS_BORDER or ES_MULTILINE or ES_WANTRETURN or \
WS_VSCROLL or WS_HSCROLL or ES_AUTOVSCROLL or ES_AUTOHSCROLL, \
7,7,113,65,IDC_EDIT
DlgButton "UCASE",0,28,82,30,10,IDC_BTNU
DlgButton "LCASE",0,68,82,30,10,IDC_BTNL
CallModalDialog hInstance,0,DlgProc,NULL
exit
;==============================================================================
end start
Hi
My problem is solved and works fine
Now have i a other question to allocate memory
I need for my project more allocate memory for use 2 buffers!
I know as one might call this function 2 times .
My thinking is a other way to not use 2 times this function
My steps:
invoke VirtualAlloc,NULL,1000...
.if (eax)
mov pszMem,eax ;pszMem is now 1000 bytes reserved
mov pszMem2,eax ;[eax /2]
.endif
Now have i in pszMem2 500 bytes or?
And by VirtualFree
VirtualFree,pszMem,1000,MEM_DECOMMIT
Now is pszMem and pszMem2 free
Could this work?
.if (eax)
mov pszMem,eax ;pszMem is now 1000 bytes reserved
add eax, 500 ; NOW you have 2*500 bytes of buffer
mov pszMem2,eax ;[eax /2]
.endif
Thanks for your post
I hope i understand this correct ::)
mov pszMem,eax ;is the pointer to the allocated memory with 1000 bytes
add eax, 500 ;add to this pointer 500
mov pszMem2,eax
Then have i in pszMem 500 bytes and in pszMem2 500bytes?
Why say you 2*500 bytes of buffer?
Greets
2 x 500 = 1000
you are allocating 1000 bytes and splitting it into two 500-byte buffers
when you free the allocated block, you will only need to free the original 1000-byte block base address (handle)
Quote from: oex on July 18, 2010, 06:57:56 PM
Quote from: ragdog on July 18, 2010, 06:36:31 PM
invoke VirtualFree, pszMem,nSize,MEM_RELEASE
If you specify this value, dwSize must be 0 (zero)
invoke VirtualAlloc,0,8192,MEM_COMMIT or MEM_RESERVE,PAGE_READWRITE
mov pszMem,eax
invoke VirtualFree, pszMem,0,MEM_RELEASE
print str$(eax)
inkey
eax prints '1'
This is what I always use. I allocate a huge hunk, then completely free it when I am done.
Dave.
Just for the record, it's rather fruitless to reserve anything less than 64k of memory using VirtualAlloc; While windows will reserve things 4K at a time, it positions them on 64K aligned boundaries. Consequently, reserving less than that essentially wastes all the other address space, which can never be used. To be totally optimal, you should reserve 64K chunks of address space at a time, and then commit them 4K at a time, as needed. If you have lots of smaller allocations, the heap is a more convienent option
-r
Quote from: redskull on July 25, 2010, 07:09:48 PM
Just for the record, it's rather fruitless to reserve anything less than 64k of memory using VirtualAlloc; While windows will reserve things 4K at a time, it positions them on 64K aligned boundaries. Consequently, reserving less than that essentially wastes all the other address space, which can never be used. To be totally optimal, you should reserve 64K chunks of address space at a time, and then commit them 4K at a time, as needed. If you have lots of smaller allocations, the heap is a more convienent option
-r
The following is a map of all of the memory I can allocate in one of my programs:
Base Size End
Bases
0x004075C7 00 00 41 00 ; 41000000 7c3f0000 BD3F0000
0x004075CB 00 00 b2 7c ; 7cb20000 02bd0000 7F6F0000
0x004075CF 00 00 7f 7f ; 7f7f0000 007bf000 7FFAF000
0x004075D3 00 00 32 00 ; 00320000 000df000 3FF000
0x004075D7 00 00 00 00 ;
0x004075DB 00 00 00 00 ;
0x004075DF 00 00 00 00 ;
0x004075E3 00 00 00 00 ;
0x004075E7 00 00 00 00 ;
0x004075EB 00 00 00 00 ;
Size
Sizes
0x004075EF 00 00 3f 7c ; 7c3f0000
0x004075F3 00 00 bd 02 ; 02bd0000
0x004075F7 00 f0 7b 00 ; 007bf000
0x004075FB 00 f0 0d 00 ; 000df000
0x004075FF 00 00 00 00 ;
0x00407603 00 00 00 00 ;
You will notice that the last 2 allocations are not mod 64K in size, in fact they are mod 4K. I allocate these by trying to get the biggest piece I can, then saving the base and size. Then I try again up to 9 more times, getting smaller and smaller pieces.
If I limited myself to 64K sized requests, I would not get the 30 4K blocks (f000 of 007bf000) and (f000 of 000df000).
To be sure, you need to temper this. I allocated all available memory then forced an error (load from location 0). The program terminated with no message. I then started allocating space between the first and subsequent allocations with a 4K block, and freed the special space after I got the last available block, then I tried the bad access. I grew this special block until Visual Studio could be brought in to report the error. I then hardcoded this special size. I now get the biggest piece, the special block, then the remaining space, then free the special block. No more problems.
Dave.
The size of existing allocations is not related to the allocation granularity; it's the BASE that is configured to mod 64k. For example, the allocation at 320000 is base 64K, and the 'end' is at 003FF000. That means all the address space between 003FF001 and 040000 is now both inaccessible and unallocable.
-r
I understand. What I am saying is that you forgo some amount (in my case 30 4K blocks) of memory you could allocate (and then dispense in 4K blocks) if you only ask for blocks of 64K. The system could not give me the extra 4K at the end of that allocation because something was loaded there.
Dave.