Is it possible to pass a local variable (variable taking up space on the stack) to another procedure? Obviously, when moving to another procedure causes a new stack frame to be created and the esp/ebp registers no longer will match what they were before. However, let's say I had:
and I want to pass Str_Escaped to a string that actually generated an escaped string. Obviously the variable being on the stack is not going to have a heap address, and the complexities of the stack frames being different once control-flow is passed to another function , would it be possible to take the absolute address of the variable sitting on the stack and pass that to another function?
I'd like to have the Escape_String procedure operate on the stack location that Str_Escaped (now stored in edx) is sitting at. However, it doesn't seem to work correctly. It's not failing, but it's value is never changed. It's changed in the "current" stack frame of the new procedure, but not of the calling procedure. I could always set eax to the value and return that and then set it in the calling procedure, but I'd like the procedure to be able to operate on a passed in local if possible.
Is this not working (or maybe not possible) because the address is based on a "relative" position and upon entering another procedure the relative position is no longer correct? Thanks!
You can certainly take the address of a local variable; after all, [esp+X] resolves to an absolute address, so when you use it in lea, you get an "absolute" address, even though 'X' is relative to esp. This is very common actually, but only if the called function is down the stack chain.
Note that you can't use that address to a function "above" yours (i.e. your function returns to it) because then the address points below 'esp' which is considered invalid and can be trashed by any other calls etc.
The stack is not super special. It's just a memory region, like the heap, and esp is just a normal pointer to it. It has a few "special" quirks (mostly due to the OS, not the processor) but you don't need to worry about that right now (it's low level stuff with exceptions).
Everytime you call or push something on the stack, the pointer gets decremented. Any address above the pointer is valid to pass around other functions, so as long as esp is below your "address" that you pass to another function, it's perfectly fine and common.
I don't know why it's not working, but your code looks valid to me, I suspect Escape_String is wrong itself. Did you take the value from the stack and then dereference it? Showing Escape_String will solve the problem.
Joined: 24 Aug 2004
Location: Misner space
Str_Escaped is only four bytes in length, three bytes for characters and one byte for the terminating zero. Are you sure it isn't a pointer to a string? If it is then you push the value of the pointer, not the address of the pointer.
pushdword[Str_Escaped] ;<--- push the value?
BTW: If you remove the colon then you can remove the size override.
@Furs ok I think I got it working. It seems I had to lea the variable to a register and pass that, and then inside the procedure I had to lea the parameter again (for when I pass it to my memory allocation procedure). It's kinda screwy but I think it makes sense now. I needed the first lea for the stack address (didn't want to use hardset/static relative-addresses) but then when they gets passed to another procedure, that value gets put into a "temporary" that is... on the stack. thus, I then had to lea that parameter since being in the new procedure is another stack frame all of its own (which I know... it just didn't dawn on me). Either way, I'm going to have to abandon using the local variables though I think (or at least accessing them directly) because it seems when I come back from that second routine, esp's address goes higher pushing the modified parameter quite a bit lower since that second procedure does a bunch of other stuff as well. I could allocate something on the heap and pass that around, I could use globals, etc. There's some options but I think I'm definitely going to have to think this through. Thanks!
@revolution since my original post, I have modified the code. It now looks like
Str_Escaped rd 4
You did say something rather interesting... I thought addresses even as values are still stored as 4 bytes, because the registers are 4 hexadecimal values (on 32-bits) and memory addresses are natively DWORDs (on 32-bits)? I'm pretty sure I've seen addresses butted right up next to each other with no null-terminator in between. Is that incorrect? Should there still be null-terminators. I feel like, obviously, strings needs null-terminators, but memory addresses it's assumed to be 4-bytes, though I guess depending on how they're being read (is a variable already set to its value and you're passing that around vs. actual string parsing of that memory address) it could matter.
Joined: 24 Aug 2004
Location: Misner space
If you are storing string data at the address Str_Escaped then it might be more prudent to define it as byte data
Str_Escapedrb16;16 bytes of data
When you use "rd 4" you still reserve 16 bytes (4 dwords) but the label is tagged as dword data. This "works" if you only ever use LEA to get the address but it makes the code harder to understand.
For 32-bit code addresses are indeed 4 bytes, you don't need any terminator bytes between them. But don't confuse the address with the value at the address. You can use a 32-bit register to point to the address of a single byte
movesi,var;<--- esi is a 32-bit address pointer to the single byte 0x12
moval,[esi] ;<--- al now has the value 0x12
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