Is the instruction after a RET always the one after CALL?

Started by mateustymbu, March 06, 2012, 09:49:10 PM

Previous topic - Next topic

mateustymbu

Hi guys!

In a well-behaved C program, shall the return statement (RET) always return to the instruction following the CALL statement? I know this is the default, but I would like to check if anyone knows or remembers authentic examples of cases where this standard does not apply (common compiler optimization or other things...).

Thank you very much,

Mateus.

dedndave

yes - the first instruction after the CALL is executed after RET

CALL pushes the address of the following instruction on the stack, then jumps to the called address
when RET is executed, the address is popped off the stack and into the IP (or EIP) register

jj2007

You better check with Olly... the first instruction after the ret is not the nop :wink

include \masm32\include\masm32rt.inc

MyTest   PROTO C :DWORD, :DWORD

.code
AppName   db "Masm32 is great!", 0
Hello   db "A message:", 0

start:
   invoke MyTest, offset AppName, addr Hello
   nop
   exit

MyTest proc C arg1:DWORD, arg2:DWORD
  MsgBox 0, arg1, arg2, MB_OK
  ret
MyTest endp

end start


hutch--

Mateus.

In normal circumstances the CALL RET pair work as Dave has described but it is worth understanding how it works with the address pushed onto the stack. In most instances maintaining this pairing is the best way to go as it is optimised in the processor to work this way but note that it is not the only way a procedure can be done, some people code a jump to the address on the stack and you can of course modify the address on the stack so the RET returns to a different address.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

clive

The classic example would be embedding in-line strings, where the subroutine would pull the return address and advance it.

  call print_string
  db  "Test String1$"
  call print_string
  db  "Test String2$"
It could be a random act of randomness. Those happen a lot as well.

clive

Quote from: jj2007You better check with Olly... the first instruction after the ret is not the nop

And INVOKE isn't CALL, using macros or high level constructs will obfuscate the actual opcodes generated.

For more fun, MIPS has a prefetch slot after branch or call instructions that execute BEFORE the code flow changes.
It could be a random act of randomness. Those happen a lot as well.

mineiro

To give you an idea, follow tracing in a debug.
include masm32rt.inc
.code
start:
push that_place ;emulated call 1
jmp some_place
that_place: ;emulated call 2
push exiting
push some_place
ret
exiting:
invoke ExitProcess,0
some_place:
ret
end start

mateustymbu

Wow! Thanks for all the answers! You are really fast!

[section deleted]

hutch, you addressed the key point of my question, but I do not know if I expressed it right. As a junior developer of exploits (just learning), I know that we can use other structures to change the execution flow... My concern is whether the commercial application programs in general, compiled by tools (in contrast to programs written directly in assembly by skilled programmers, like you) ALWAYS follow the mentioned pattern. Notice that in this case I have a fixation for exceptions (it is important to know whether they exist in this case, for a research project I'm developing into a M. Sc. program's discipline. No, I'm not a blackhat!). I know, for example, that a compiler may, sometimes, change a RET to a JMP (tail-call optimization). I would like to know if something like this may change the order of the instruction that is executed after the RET and, mainly, if the CALL will always be just before the instruction executed after the RET. 

clive and mineiro, as I said to jj2007, I'm not able to execute or understand very well your code, but I will work on it. Thanks.

Thanks everybody. I would be grateful if you can solve my questions.

clive

So exploits, the x86 doesn't provide PC relative addressing, and no explicit way to get EIP into a register, so if you need to figure out where your code is loaded.

  call @F ; MOV EAX,EIP address of @@
@@: pop eax
It could be a random act of randomness. Those happen a lot as well.

hutch--

I have re-opened this topic after the original poster explained what he is doing. We cannot allow reference to illegal topics or techniques that can be used illegally so please keep any further posts within the rules of the forum.

If there are any further references to illegal content we will have to delete this topic.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php