Announcement

Collapse
No announcement yet.

One for you ASM gurus

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • One for you ASM gurus

    Is there any sure fire way to tell what instruction
    caused invocation of the current instruction? Specifically, Is there
    a register or EBP, ESP offset that one can check to get the addresss
    of the instruction that invoked a subroutine?
    Here is the scenario:
    In a program I am writing, I am hooking the JMP statements to
    various sub-routines by replacing the JMP instruction with an
    instruction to JMP to my sub-routine. I then call the "real"
    sub-routine. I get access before and after the "real" sub-routine so
    I can do timings and debug stuff.

    Any help would be greatly appreciated.


    ------------------
    R.

  • #2
    Randy:

    I'm a little unclear on exactly what it is you're up to... normally, one does not invoke subroutines (note emphasis) with JMP instructions, precisely because there's no way for the routine that was jumped into to know where to jump back when its finished. (At least none I know of - but I admit to not being "up" on all the weird extensions and special registers crammed into the Pentium-and-beyond CPUs, so someone feel free to correct me if I'm wrong.) Primarily, JMP instructions are used to control execution flow, when the program must take one of several branches depending on the outcome of a calculation, but all of those branches need to return to a common point for execution to continue.

    Subroutines are generally invoked via CALL and RETURN - in which case, the address the CALL was invoked from (or, more accurately, the instruction immediately following the CALL) is available to you on the top of the stack, and you could POP it into a register pair for examination. (Be sure to immediately PUSH it back, though, or things'll get really nasty! )

    ------------------

    Comment


    • #3
      I forgot to mention that the place where I am patching the code
      is a JMP statement that is "jumped to" from a CALL statement. And
      therein lies my dilemna. I know the return address is at EBP + 4
      (this is the instruction after the CALL statement). What I want to
      get my grubby little paws on is the address of the JMP statement
      that really jumped to my subroutine.


      ------------------
      R.

      Comment


      • #4
        Gary you are correct.
        A jmp statement does not push the return address onto the stack.
        Call statements do push the return address and you could just pop it
        off the stack, examine it, and push it back on.

        I supose you could also push some value onto the stack right before the jmp statement then
        pop it off and examine that to see where the jmp statement came from.
        Or you could put a value into one of the general registers, since they
        will remain intacted after the jmp call and read it in the called
        proceedure.

        I think the best way is to use the CALL statement and examine the IP off
        the stack.

        ------------------
        mailto:[email protected][email protected]</A>

        Comment


        • #5
          Randy,
          why not put a PUSH EIP right before your jmp statement? Then just pop
          that off the stack. Then the next instruction after that is the one
          you are looking for.


          ------------------
          mailto:[email protected][email protected]</A>

          Comment


          • #6
            Randy,

            I fail to see the problem, why don't you patch in a CALL instruction instead of a JMP?
            If the space is too small to patch a CALL in, use an 2 byte INT xx instruction (be sure to fill the rest with NOPs).
            Your return address will always be right where your patches were made.

            Am I missing something here?


            Peter.


            ------------------
            [email protected]

            Comment


            • #7
              Randy--

              An interactive disassembler allows you to do what you want to.

              What tools are you working with now?


              ------------------
              -- Greg
              [email protected]

              Comment


              • #8
                This thread looks enough strange.
                If to speak about own program, there are CALL DWORD / GOTO DWORD instructions, which allow to select a subroutine or where to jump.
                If this is a patch of external program, I'm sorry ...

                [This message has been edited by Semen Matusovski (edited July 17, 2000).]

                Comment


                • #9
                  Perhaps I should give a little more detailed explanation.
                  The purpose of the program I am writing is to give timing information
                  on the subroutines of a running executable without having to modify
                  the source code in any way. to accomplish this I am writing a dll that will be
                  "injected" into the process of this running executable (not of my making). I know that this
                  running executable has a table of JMP statements that I want to hook. I save the "jumped to"
                  address and replace the JMP instruction with a JMP to my subroutine.
                  There is not enough space to insert a CALL statement (that was my
                  first idea). If I were to insert an INT xx instruction instead, then I would have
                  to hook whatever interrupt vector I was invoking as well, wouldn't I?

                  ------------------
                  R.

                  Comment


                  • #10
                    - - - - - - - - - -
                    Randy Standridge wrote:
                    If I were to insert an INT xx instruction instead, then I would have
                    to hook whatever interrupt vector I was invoking as well, wouldn't I?

                    - - - - - - - - - -

                    That is correct. However, hooking an INT vector isn't particularly hard, at least in DOS... (I presume Windows has services for it as well.) The hairiest part, usually, is choosing an INT that isn't already claimed by some other program or driver...

                    Unfortunately, there just isn't any sure-fire way for the target of a JMP instruction to determine where it was "jumped from", since the source address is not saved anywhere by the CPU. (The reasonable assumption being that's what CALL/RETURN is for.) In short, you can't get there from here.

                    However, in light of these two comments:
                    - - - - - - - - - -
                    I forgot to mention that the place where I am patching the code
                    is a JMP statement that is "jumped to" from a CALL statement.


                    I know that this running executable has a table of JMP statements that I want to hook. I save the "jumped to" address and replace the JMP instruction with a JMP to my subroutine.
                    - - - - - - - - - -
                    If I understand correctly, you might be able to pull it off, but it'll be a little convoluted. It sounds as if the program in question is making CALLs to a vector table, correct? In that case, the return address, which is still on the stack, will be the instruction following the CALL. Just have your timing-test code snag that address from the stack, then examine the instruction immediately preceeding it. By examining the CALL instruction itself, you can find the address of the JMP instruction it CALLed in the vector table, which I think is what you're looking for...(?)

                    ------------------

                    Comment

                    Working...
                    X