2009-06-10 6 views
2

J'étudie actuellement un programme que j'ai écrit en assembleur et je pensais à déplacer du code dans l'assemblage. J'ai une procédure qui prend un argument, mais je ne suis pas sûr si elle est passée sur la pile ou un registre.Les arguments d'une fonction seront-ils transmis sur la pile ou dans un registre?

Quand j'ouvre mon programme IDA Pro, la première ligne de la procédure est la suivante:

ThreadID= dword ptr -4 

Si je passe la souris mon curseur sur la déclaration, ce qui suit apparaît également:

ThreadID dd ? 
r db 4 dup(?) 

qui Je suppose que pointerait vers une variable de pile? Quand j'ouvre le même programme dans OllyDbg cependant, à cet endroit sur la pile il y a une grande valeur, ce qui serait incompatible avec tout paramètre qui aurait pu être passé, ce qui me laisse croire qu'il est passé dans un registre .

Quelqu'un peut-il me diriger dans la bonne direction?

Répondre

0

La façon dont les arguments sont transmis à une fonction dépend de la fonction calling convention. La convention d'appel par défaut dépend du langage, du compilateur et de l'architecture. Je ne peux rien dire à coup sûr avec les informations que vous avez fournies, mais vous ne devez pas oublier que les débogueurs au niveau de l'assemblage comme OllyDbg et les désassembleurs comme IDA utilisent souvent des heuristiques pour désosser le programme. La meilleure façon d'étudier le code généré par le compilateur est de lui demander d'écrire des listes d'assemblage. La plupart des compilateurs ont une option pour le faire.

+0

La convention d'appel est __fastcall – samoz

+1

« En règle générale fastcall les conventions d'appel passent un ou plusieurs arguments dans les registres qui réduit le nombre de accès mémoire requis pour l'appel. » - http://en.wikipedia.org/wiki/X86_calling_conventions#fastcall –

+1

Encore une chose que je n'ai pas remarquée. Les offsets positifs dans la pile (par rapport au pointeur de base) sont des variables locales, donc ThreadID est probablement une variable locale. –

0

C'est une variable locale à coup sûr. Pour vérifier les arguments, recherchez les valeurs [esp + XXX]. L'IDA les nomme automatiquement [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 

Et convention fastcall comme cela a été décrit dans le commentaire ci-dessus utilise des registres pour transmettre des arguments. Je parierais sur le compilateur Microsoft ou GCC car ils sont plus largement utilisés. Vérifiez donc les registres ECX et EDX en premier.

Microsoft ou GCC [2] __fastcall [3] Convention (alias __msfastcall) passe les deux premiers arguments (évalués gauche à droite) qui se logent dans ECX et EDX . Les arguments restants sont poussés sur la pile de droite à gauche. http://en.wikipedia.org/wiki/X86_calling_conventions#fastcall

Questions connexes