2010-10-12 8 views
0

du studio visuel Dumped:Pourquoi l'assemblage ne me semble pas cohérent?

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) 

Mais la définition actuelle est:

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

Bien que mon montage n'est pas si bon, je ne vois pas de relation entre la source et asm.

Répondre

3

Vous l'avez omis suffisamment pour être sûr, mais la partie qui peut être triée semble raisonnable. NULL == 0, donc:

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. 

Le problème évident est que vous ne nous avez pas montré ce qui est en 17D617Dh ou 17D62D7h, donc nous ne pouvons pas deviner vraiment ce qui est vraiment fait avec les valeurs.

+0

Le vrai Ollydbg sait certainement! Un 'jmp' commence à exécuter du code à une adresse spécifiée. Un 'call' fait la même chose, mais d'abord il pousse l'adresse actuelle sur la pile de sorte qu'un' ret' peut continuer à retourner là-bas. –

+0

Non adresse actuelle, mais l'adresse d'instruction suivante pour être exact. – ollydbg

+0

@ollydbg: Je voulais vraiment quelque chose de plus comme "adresse actuellement dans EIP", mais oui, ce sera l'adresse suivant l'instruction actuelle (bien que dans les processeurs vraiment * tôt * x86 ce n'était pas le cas - qui a causé un problème avec gestion des exceptions dans quelques cas bizarres). –

0

probable

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 se trouve être situé à l'adresse stockée sur la pile - il accède généralement par l'intermédiaire d'indirection à l'aide d'une mémoire de valeurs dans ebp.

Cette valeur est comparée à nulle et si elle est nulle (jne ne se déclenche pas) une valeur réelle de E_POINTER est déplacé à eax (eax est utilisé pour stocker la valeur de retour de la fonction) et le contrôle est passé à l'épilogue de la fonction où le nettoyage est effectué, puis le contrôle est renvoyé à l'appelant (instruction ret). Si la valeur de pReceivePin n'est pas nulle (jne ne démarre pas), le contrôle est transmis à un autre emplacement où le code qui s'est passé après CheckPointer est stocké et ce code est ensuite exécuté.

+0

Pourquoi est-ce que vous mentionnez 'ret', il n'y a pas une telle instruction dans mon vidage vs, n'est-ce pas? – ollydbg

+0

@ollydbg: C'est ailleurs. Essayez d'appeler ce code avec 'pReceivePin' étant null - code va exécuter' jne' et arriver à l'epligue où 'ret' est. – sharptooth

0

Vous devez fournir plus de contexte, mais très probablement, la dernière ligne saute aux parties finalizing de la fonction CBasePin :: Connect, qui suit avec un RET rapidement. C'est assez cohérent avec la logique de votre macro. La deuxième ligne saute juste après la dernière ligne si le pointeur n'est pas nul (c'est-à-dire nul).

0

L'assemblage semble parfaitement bien.

cmp dword ptr [ebp+0Ch],0 est la comparaison sur pReceivePin avec NULL. pReceivePin est une variable locale à l'intérieur de votre fonction, son adresse est donc un décalage par rapport au début du cadre de pile de la fonction. ebp contient l'adresse du début de la trame de la pile. 0Ch est le décalage de pReceivePin à l'intérieur du cadre de la pile. Toutes les variables locales de votre fonction seront appelées [ebp + something], à l'exception des paramètres. Les paramètres sont généralement appelés [ebp - something].

mov eax,80004003h est rien d'autre que E_POINTER valeur placée dans la zone « valeur de retour » de la fonction (registre eax est utilisé à cette fin).

Le jmp dernier envoie le contrôle au code de l'épilogue de la fonction de courant (CBasePin::Connect), qui se termine dans la commande ret (et « retours » la valeur eax actuelle, à savoir E_POINTER)

Le milieu jne sens contrôle de la code immédiatement après votre macro, si pReceivePin n'est pas égal à E_POINTER.

+0

Pourquoi 'pReceivePin' est-il développé à' [ebp + 0Ch] '? – ollydbg

+0

@ollydbg: Il est stocké dans la pile et est accessible via l'indirection. – sharptooth

+0

@ollydbg: Voir la modification. – AnT

Questions connexes