0

Morning, I've implemented a cdecl call method into the following 'encryption' routine. However whilst my method works, it's not following the recommended (uni and other sources) exactly.

Advise appreciated (Some comments may be 'wrong' cdecl related functs have be marked for)

My confusion is that I've been told that for each parameter pushed (in this case 2) I must push before the call, push again inside the funct, then do mov [ebp+n] for each additional push - before the main body.

However if I follow the logic of : do a mov ebp shift for every push - without adding additional pushes, all works fine. But this could well be an error.

If required I can post some of reference docs.

code extract:

void encrypt_chars (int length, char EKey)
{char temp_char;                        // Character temporary store

for (int i = 0; i < length; i++)    // Encrypt characters one at a time
{
    temp_char = OChars [i];         // Get the next char from Original Chars array
                                    // Note the lamentable lack of comments below!
    __asm {                         //
        push   eax                  //making a copy of char to be encrypted index 
        push   ecx                  //making a copy of the char to be encrypted
                                    //
        movzx  ecx,temp_char        //padding out temp_char
        lea    eax,EKey             //moving Ekey adress to eax, for function to use, eax contents acting as perameter
        call   encrypt6             //Doing the encryption
        add esp, 8  //cdecl added stack pointer baxk
        mov    temp_char,al         //Move the encrypted result into temp_char
        pop    ecx                  //resetting registers to before call
        pop    eax                  //
    }
    EChars [i] = temp_char;         // Store encrypted char in the Encrypted Chars array
}
   return;


// Encrypt subroutine. You should paste in the encryption routine you've been allocated from Bb and
// overwrite this initial, simple, version. Ensure you change the ‘call’ above to use the
// correct 'encryptnn' label where nn is your encryption routine number.
// 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 {


encrypt6: 
             push ebp                  //cdecl Making a copy of base pointer
             mov ebp, esp             //cdecl storing the point at which the base pointer has shifted the stack         


            // push ecx //cdecl         
            // push eax //cdecl

        //   mov ecx, [ebp + 12] // cdecl storing Ekey adress
        //   mov eax, [ebp + 8]  //cdecl storing temp_char data             



             ror byte ptr[eax], 1      //Rotating the EKey data right 6 times
             ror byte ptr[eax], 1      //
             ror byte ptr[eax], 1      //
             ror byte ptr[eax], 1      //
             ror byte ptr[eax], 1      //
             push ecx                  //Making a copy of ecx

             mov ecx, [ebp + 8] // cdecl ,

             not byte ptr[eax]         //Inverting the Ekey data 
             movzx edx, byte ptr[eax]  //making a copy of the ekey data with leading zero's
             pop eax                   //restoring register to thet temp_char ascii value
             xor eax, edx              //XORing original temp_char with encrypted temp_Char 
             ror al, 1                 //Rotating the Ekey adreses 8 bit component right twice (To edit)
             ror al, 1                 //
             not al                    // Inverting the result
             add eax, 0x20             // adding a space (32) to result


             pop ebp //cdecl ,pop ebp
             ret //cdecl

        //----

}
  • 1
    If the code works, it's probably more suitable for https://codereview.stackexchange.com/ – Sami Kuhmonen Mar 09 '16 at 09:10
  • The cdecl calling convention is passing parameters on the stack, but your code passes them in registers. Is that part of the confusion? When one assembly routine calls another one, you can do whatever you want, so that is not a problem in itself. – Bo Persson Mar 09 '16 at 09:38
  • Thanks for the comments, I'll post the provided docs later. And yes I may post it on code review if there isn't a problem with my method – Jamie Nicholl-Shelley Mar 09 '16 at 12:21
  • The most obvious optimization would be `ror byte ptr[eax], 6` instead of repeating a load/modify/store rotate-by-1 instruction 6 times!! Or better, just keeping the byte value in a register, like you do later after eventually doing a `movzx` load and then working with AL. – Peter Cordes Feb 17 '21 at 03:41

0 Answers0