2015-03-19 1 views
-1

J'ai dû implémenter une convention d'appel cdecl dans ce programme qui utilisait à l'origine une convention non standardisée. Pour autant que je peux dire qu'il semble correct, mais je reçois une erreur d'exception non gérée en disant "Accusé de violation d'écriture emplacement 0x00000066, qui semble frapper quand le programme descend à la ligne" pas byte ptr [eax] "ou au moins c'est où la flèche après la rupture du programme.Cryptage simple Programme d'assemblage - violation d'accès d'écriture à l'emplacement de la mémoire

quelqu'un pourrait-il me dire ce qui ne va pas avec mon programme et comment je peux résoudre ce problème? Merci.

void encrypt_chars (int length, char EKey) 
{ char temp_char;      

for (int i = 0; i < length; i++)  
{ 
    temp_char = OChars [i];   
    __asm { 
      push eax 
      movzx eax, temp_char 
      push eax 
      lea eax, EKey 
      push eax 
      call encrypt 
      mov temp_char, al 

      pop eax 
    } 
    EChars[i] = temp_char;   
return; 


// Inputs: register EAX = 32-bit address of Ekey, 
//     ECX = the character to be encrypted (in the low 8-bit field, CL). 
// Output: register EAX = the encrypted value of the source character (in the low 8-bit field, AL). 

__asm {   

encrypt: 

     push ebp 
     mov ebp, esp 
     mov ecx, 8[ebp] 
     mov eax, 12[ebp] 
     push edi     
     push ecx     
     not byte ptr[eax]   
     add byte ptr[eax], 0x04 
     movzx edi, byte ptr[eax] 
     pop eax     
     xor eax, edi    
     pop edi     
     rol al, 1     
     rol al, 1     
     add al, 0x04    
     mov esp, ebp 
     pop ebp 
     ret      
} 
+1

Avez-vous essayé le déboguer? Je suppose qu'il y a aussi des débogueurs pour le code d'assemblage. – sashoalm

+1

Lol Hallam étudiant? –

Répondre

3

par inspection, le commentaire sur la fonction encrypt est erroné Rappelez-vous: la pile augmente vers le bas, donc quand les arguments sont poussés sur la pile, ceux qui sont poussés en premier ont l'adresse la plus élevée et, par conséquent, le décalage le plus élevé du pointeur de base le cadre de la pile.

Le commentaire à encrypt dit:

// Inputs: register EAX = 32-bit address of Ekey, 
//     ECX = the character to be encrypted 

Cependant, votre séquence d'appel est:

movzx eax, temp_char ; push the char to encrypt FIRST 
push eax 
lea eax, EKey   ; push the encryption key SECOND 
push eax 
call encrypt 

Ainsi, le personnage est de pousser premier. Ainsi, le caractère à chiffrer Mais encrypt est de les charger de cette façon:

; On function entry, the old Instruction Pointer (4 bytes) is pushed onto the stack 
; so now the EKey is +4 bytes from the stack pointer 
; and the character is +8 bytes from the stack pointer 
; 

push ebp 
mov ebp, esp 

; We just pushed another 4 bytes onto the stack (the esp register) 
; and THEN we put the stack pointer (esp) into ebp as base pointer 
; to the stack frame. 
; 
; That means EKey is now +8 bytes off of the base pointer 
; and the char to encrypt is +12 off of the base pointer 
; 
mov ecx, 8[ebp]   ; This loads EKey pointer to ECX 
mov eax, 12[ebp]   ; This loads char-to-encrypt to EAX 

Le code procède ensuite à essayer de faire référence EAX comme un pointeur (car il pense que ce EKey), qui va provoquer une violation d'accès car il est votre personnage pour crypter la première fois qu'il essaie de référencer EAX comme un pointeur, qui est ici:

not byte ptr[eax] 

Ainsi, votre pointeur de débogueur avait raison! :)

Vous pouvez fixer simplement en échangeant ces deux registres:

mov eax, 8[ebp]   ; This loads EKey pointer to EAX 
mov ecx, 12[ebp]   ; This loads char-to-encrypt to ECX 

Enfin, votre appel à chiffrer ne nettoie pas le pointeur de la pile quand il est fait. Puisque vous a poussé 8 octets de données sur la pile avant d'appeler encrypt, et depuis encrypt-t un ret standard sans nettoyage de la pile, vous devez nettoyer après l'appel:

... 
call encrypt 
add esp, 8 
... 
+0

Merci beaucoup, cela m'a complètement éclairci, je suis nouveau à ce sujet, cela m'a vraiment aidé à savoir où je me suis trompé. – JohnnyCage69