views:

144

answers:

2

I'm currently analyzing a program I wrote in assembly and was thinking about moving some code around in the assembly. I have a procedure which takes one argument, but I'm not sure if it is passed on the stack or a register.

When I open my program in IDA Pro, the first line in the procedure is:

ThreadID= dword ptr -4

If I hover my cursor over the declaration, the following also appears:

ThreadID dd ?
 r db 4 dup(?)

which I would assume would point to a stack variable?

When I open the same program in OllyDbg however, at this spot on the stack there is a large value, which would be inconsistent with any parameter that could have been passed, leading me to believe that it is passed in a register.

Can anyone point me in the right direction?

A: 

The way arguments are passed to a function depends on the function's calling convention. The default calling convention depends on the language, compiler and architecture.

I can't say anything for sure with the information you provided, however you shouldn't forget that assembly-level debuggers like OllyDbg and disassemblers like IDA often use heuristics to reverse-engineer the program. The best way to study the code generated by the compiler is to instruct it to write assembly listings. Most compilers have an option to do this.

CyberShadow
The calling convention is __fastcall
samoz
"Typically fastcall calling conventions pass one or more arguments in registers which reduces the number of memory accesses required for the call."-- http://en.wikipedia.org/wiki/X86_calling_conventions#fastcall
CyberShadow
One more thing I didn't notice. Positive offsets in the stack (relative to the base pointer) are local variables, so ThreadID is most likely a local variable.
CyberShadow
A: 

It is a local variable for sure. To check out arguments look for [esp+XXX] values. IDA names those [esp+arg_XXX] automatically.

.text:0100346A sub_100346A     proc near               ; CODE XREF: sub_100347C+44p
.text:0100346A                                         ; sub_100367A+C6p ...
.text:0100346A
.text:0100346A arg_0           = dword ptr  4
.text:0100346A
.text:0100346A                 mov     eax, [esp+arg_0]
.text:0100346E                 add     dword_1005194, eax
.text:01003474                 call    sub_1002801
.text:01003474
.text:01003479                 retn    4
.text:01003479
.text:01003479 sub_100346A     endp

And fastcall convention as was outlined in comment above uses registers to pass arguments. I'd bet on Microsoft or GCC compiler as they are more widely used. So check out ECX and EDX registers first.

Microsoft or GCC [2] __fastcall[3] convention (aka __msfastcall) passes the first two arguments (evaluated left to right) that fit into ECX and EDX. Remaining arguments are pushed onto the stack from right to left. http://en.wikipedia.org/wiki/X86_calling_conventions#fastcall

Stanislav