2009-06-10 1 views
2

В настоящее время я анализирую программу, которую я написал в сборке, и думал о перемещении некоторого кода в сборке. У меня есть процедура, которая принимает один аргумент, но я не уверен, передан ли он в стек или регистр.Будут переданы аргументы функции в стек или в регистр?

Когда я открываю программу в IDA Pro, первая строка в процедуре является:

ThreadID= dword ptr -4 

Если я парить мой курсор над декларацией, следующее также появляется:

ThreadID dd ? 
r db 4 dup(?) 

который Я бы предположил, что это указывает на переменную стека?

Однако, когда я открываю ту же программу в OllyDbg, в этом месте на стеке есть большое значение, которое было бы несовместимо с любым параметром, который мог быть передан, что заставило меня поверить, что оно передается в регистр ,

Может ли кто-нибудь указать мне правильное направление?

ответ

0

Способ передачи аргументов функции зависит от функции calling convention. Стандарт вызова по умолчанию зависит от языка, компилятора и архитектуры.

Я не могу сказать ничего точно с предоставленной вами информацией, однако вы не должны забывать, что отладчики на уровне сборки, такие как OllyDbg и дизассемблеры, такие как IDA, часто используют эвристику для обратной инженерии программы. Лучший способ изучить код, сгенерированный компилятором, - дать ему указание написать списки сборок. Большинство компиляторов имеют возможность сделать это.

+0

Вызывающий конвенция __fastcall – samoz

+1

«Как правило азЬсаИ соглашения о вызовах передать один или более аргументов в регистрах, что уменьшает количество обращений к памяти требуется для вызова.» - http://en.wikipedia.org/wiki/X86_calling_conventions#fastcall –

+1

Еще одна вещь, которую я не заметил. Положительные смещения в стеке (относительно базового указателя) являются локальными переменными, поэтому ThreadID скорее всего является локальной переменной. –

0

Это локальная переменная точно. Чтобы проверить аргументы, найдите значения [esp + XXX]. IDA автоматически называет те [esp + arg_XXX].

.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 

И соглашение fastcall, как было указано в комментарии выше, использует регистры для передачи аргументов. Я бы поставил на компилятор Microsoft или GCC, поскольку они более широко используются. Поэтому сначала проверьте ECX и EDX.

Microsoft или GCC [2] __fastcall [3] конвенции (ака __msfastcall) проходит первые два аргумента (вычисляемый слева направо), которые вписываются в ECX и EDX . Остальные аргументы помещаются в стек справа налево. http://en.wikipedia.org/wiki/X86_calling_conventions#fastcall