views:

77

answers:

4

Dumped from visual studio:

    CheckPointer(pReceivePin,E_POINTER);
017D616D  cmp         dword ptr [ebp+0Ch],0 
017D6171  jne         CBasePin::Connect+4Dh (17D617Dh) 
017D6173  mov         eax,80004003h 
017D6178  jmp         CBasePin::Connect+1A7h (17D62D7h) 

But the actual definition is:

#define CheckPointer(p,ret) {if((p)==NULL) return (ret);}

Though my assembly is not so good, I see no relation between source and asm.

A: 

Likely

 CheckPointer(pReceivePin,E_POINTER);
 017D616D  cmp         dword ptr [ebp+0Ch],0 
 017D6171  jne         CBasePin::Connect+4Dh (17D617Dh) 
 017D6173  mov         eax,80004003h 
 017D6178  jmp         CBasePin::Connect+1A7h (17D62D7h) 

pReceivePin happens to be located at address stored on stack - it is usually accesses via indirection using a value store in ebp.

That value is compared to null and if it is null (jne doesn't kick in) an actual value of E_POINTER is moved to eax (eax is used to store the return value of the function) and control is passed to the function epilogue where cleanup is done and then control is returned to the caller (ret instruction). If the value of pReceivePin is not null (jne does kick in) control is passed to some other location where code that happened to be after CheckPointer is stored and that code is then executed.

sharptooth
Why do you mention `ret `,there's no such instruction in my vs dump,right?
ollydbg
@ollydbg: It is somewhere else. Try to call that code with `pReceivePin` being null - code will execute `jne` and arrive to the epligue where `ret` is.
sharptooth
A: 

You need to provide more context, but quite possibly, the last line jumps to the finalizing parts of CBasePin::Connect function, which follows with a RET shortly. It is pretty consistent with the logic of your macro. The second line jumps right after the last line if the pointer is not zero (i.e., null).

+3  A: 

You've left out enough that it's hard to be sure, but the part that can be sorted out looks reasonable. NULL == 0, so:

017D616D  cmp         dword ptr [ebp+0Ch],0               ; if [ebp+0ch] == 0
017D6171  jne         CBasePin::Connect+4Dh (17D617Dh)    ;     goto 172617dh
017D6173  mov         eax,80004003h                       ; else load 'ret'
017D6178  jmp         CBasePin::Connect+1A7h (17D62D7h)   ;     and return it.

The obvious problem is that you haven't shown us what's at 17D617Dh or 17D62D7h, so we can't really guess at what's really being done with the values.

Jerry Coffin
The real Ollydbg certainly knows! A `jmp` starts executing code at a specified address. A `call` does the same, but first it pushes the current address on th stack so a `ret` can continue return to there.
Jerry Coffin
Not current address,but the next instruction address to be exact.
ollydbg
@ollydbg: I really intended something more like "address currently in EIP", but yes, that will be the address following the current instruction (though in really *early* x86 processors that was not the case -- which caused a problem with exception handling in a few strange corner cases).
Jerry Coffin
Right,EIP past before `jmp`.
ollydbg
A: 

The assembly looks perfectly fine.

cmp dword ptr [ebp+0Ch],0 is the comparison on pReceivePin with NULL. pReceivePin is a local variable inside your function, so its address is an offset from the beginning of the function's stack frame. ebp holds the address of the beginning of the stack frame. 0Ch is the offset of pReceivePin inside the stack frame. All local variables in your function will be addressed as [ebp + something], except for parameters. Parameters are usually addressed as [ebp - something].

mov eax,80004003h is nothing else than E_POINTER value placed into the "return value" area of the function (register eax is used for that purpose).

The final jmp sends control to the epilogue code of the current function (CBasePin::Connect), which ends in ret command (and "returns" the current eax value, i.e. E_POINTER)

The middle jne sens control to the code immediately after your macro, if pReceivePin is not equal to E_POINTER.

AndreyT
Why is `pReceivePin` expanded to `[ebp+0Ch]` ?
ollydbg
@ollydbg: It is stored in stack and is accessed via indirection.
sharptooth
@ollydbg: See the edit.
AndreyT
What's the difference between `jmp xxx` and `call xxx` then?
ollydbg