我将如何使其解密而不是加密? [英] How would i make this a decryption instead of an encryption?

查看:67
本文介绍了我将如何使其解密而不是加密?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想知道如何从加密代码中获取密码,并使用相同的代码创建解密.

Wanna know how to get this from being a encryption code and using the same code to create a decryption.

我知道这意味着我必须反转一些指令并重新排序,但我无法弄清楚哪些指令需要重新排序,哪些不需要.

I know it means that I have to reverse some of the instruction and re-order it but I can't figure out which ones need to be reordered and which ones don't.

(edit)这是使事情变得更清晰的完整功能.堆栈溢出非常新,因此很抱歉造成任何混乱.

(edit) Heres the full function to make things a bit clearer. Very new to stack overflow so apologies for any confusions.

//---------------------------------------------------------------------------------------------------------------
//----------------- ENCRYPTION ROUTINES -------------------------------------------------------------------------

void decrypt_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

    __asm                               
    {                                   
      push   eax                        // stores the "eax" register out onto the stack
      push   ecx                        // stores the "ecx" register out onto the stack
      push   edx                        // stores the "edx" register out onto the stack
                                        //
      movzx  ecx, temp_char             // zeroise "ecx" register and move values in "temp_char" varaible to "ecx" register
      lea    eax, EKey                  // copies address of values contained within the EKey varaible and moves it into "eax"register
                                        //
      push eax                          //
      push ecx                          //
                                        //
      call   decryptX                   // runs the function called "decryptX"
      mov    temp_char, dl              // move values in "dl" register into "temp_char" variable
                                        //
      add esp, 8                        // 
      pop    edx                        // removes the "edx" register from the stack
      pop    ecx                        // removes the "ecx" register from the stack
      pop    eax                        // removes the "eax" register from the stack
    }                                   //
    EChars[i] = temp_char;              // store encrypted char in the Encrypted Chars array
  }
  return;

  __asm
  {

  decryptX:
        push  ebp            // stores the pointer onto the stack

            mov   ebp, esp       // move values in "esp" register into "ebp" register
            mov   eax, [ebp + 12]// take value from the stack that is 8 bits above
                                 // from the pointer a putting it in the "eax" register
            mov   ecx, [ebp + 8] // take value from the stack that is 8 bits above 
                                 // from the pointer a putting it on ecx


            push  eax            // stores the Ekey address onto the stack
            xchg  eax, ecx       // puts temp_char's value into the EKey address register and Ekey address into temp_char register

            ror al, 1
            ror al, 1
            dec eax
            neg al


            mov   ebx, eax       // move temp_char value into "ebx" register
            pop   eax            // removes temp_char from the stack
            push  ebx            // stores temp_char value onto the stack
            pop   edx            // removes "edx" register value from the stack
            movzx ecx, [eax]     // zeroise "ecx" register and move the address stored in "eax" register to "ecx" register
            ror   cl, 1          // rotate "cl" register value in bytes to the right by 1
            xor cl, 0x96         // Exclusive OR (or XOR) the byte values within "cl" register with hex value 0x96 in binary
            push  ecx            // stores the Ekey address onto the stack
            and   cl, 0x7        // AND the byte values within "cl" register with hex value 0x7 in binary

            X:                       // Position X:

        add dl, 2            // add 2 to value within dl
            sub cl, 1            // subtract 1 from value within cl
            jg X                   // jump to "X" position
            pop   ecx            // removes "ecx" register value from the stack
            xor   ecx, edx       // exclusive OR (or XOR) the byte values within "ecx" register with the byte values within "edx" register
            mov[eax], cl         // move "cl" register value into the address stored in "eax" register.
            pop   ebp            // returning ebp back to the orginal value
            ret                  // return, end of encryptX function
  }

  //--- End of Assembly code
}
//*** end of encrypt_chars function
//--------------------------------------------------------------------------------------------------------------

推荐答案

如果这是一项家庭作业,则实际上是一项非常棘手的任务. (尽管我可能忽略了一种简单的方法.)

If this is a homework assignment, then it's actually quite a tricky one. (Though I may have overlooked a simple approach.)

让我们集中讨论此代码对内存的影响.为简单起见,我假设您对这段代码对寄存器的影响不感兴趣,尽管我不确定在看到调用此函数的代码内.

Let's focus on the effect this code has on memory. For simplicity I will assume you are not interested in the effect this code has on registers, though I cannot be sure within seeing the code calling this function.

encryptL:
    push  eax
    ...                ; ignoring this code because its effect on eax is undone by the following pop
    pop   eax
    ...                ; code not affecting eax
    movzx ecx, [eax]
    ...                ; code not affecting eax
    mov   [eax], cl
    ret

因此输入一个地址(eax).该地址处的字节放入cl,并且经过一些转换后,cl被放回相同的地址. 我们需要弄清楚这些转换是什么,然后将其反转.

So in goes an address (eax). The byte at this address is put into cl, and after some transformations, cl is put back at the same address. We need to figure out what those transformations are, and invert those.

    ror   cl, 1
    xor   cl, 0x96
    push  ecx
    ...                ; ignoring this code because its effect on ecx is undone by the following pop
    pop   ecx
    xor   ecx, edx

因此将一个旋转和两个xor应用于cl. Xor是 involution ,因此我们不必更改这两个指令. rol的倒数当然是ror,尽管并非完全如此.进位标志的作用不能反转,但是在这种情况下,该作用被忽略,所以我们很好.

So a rotate and two xors are applied to cl. Xor is an involution, so we do not have to change those two instructions. The inverse of rol is of course ror, though that is not entirely true. The effect on the carry flag cannot be inverted, but in this case that effect is ignored, so we are good.

但是我们忽略的所有代码呢?仔细检查后,您会发现只有在这里可以计算xor ecx,edx中使用的edx的值. 不幸的是,[eax]的原始(未加密)值涉及该计算. 解密时,原始值即为最终值,即xor ecx,edx的结果. 我们似乎遇到了鸡和蛋的问题.取决于相同计算结果时如何执行计算?

But what about all the code we ignored? On close inspection, you'll notice it is only there to calculate the value of edx that is used in xor ecx,edx. Unfortunately, the original (unencrypted) value of [eax] is involved in that calculation. When decrypting, the original value becomes the final value, i.e. the result of xor ecx,edx. We seem to have a chicken-and-egg problem. How to perform the calculation when it depends on the result of that same calculation?

由于以下陈述,很显然,[eax]edx的计算的影响是8种可能情况中的1种:

It should be clear that the effect of [eax] on the calculation of edx, is either 1 out of only 8 possible cases, due to this statement:

    and   cl, 0x7

这意味着我们可以使用循环来尝试所有不同的可能性,直到找到一个计算结果与在[eax]中找到的值匹配的值为止. 该循环与加密器中的该循环非常相似:

That means we can use a loop to try all different possibilities, until we found one where the result of the calculation matches the value we found in [eax]. That loop will be very similar to this loop found in the encryptor:

X:
    add   dl, 2
    sub   cl, 1
    jg    X

但是,循环的退出条件将有所不同.

However, the exit condition of the loop will be different.

    mov   bl,0        ; using bl as a loop counter (similar to cl in original loop)
X:
    inc   bl
    add   dl,2        ; same as in the original loop
    mov   cl,[eax]    ; fetch encrypted byte from memory
    xor   ecx,edx     ; try transforming cl with the current value of dl
    xor   ebx,ecx     ; compare cl with the loop counter (bl)
    and   bl,7        ; only compare the 3 least significant bits
    jg    X           ; if not zero, try again with the next possible value of dl

由于xor是可交换和关联的,因此我们可以重写此代码. 而不是递增bl直到与cl匹配,我们将递减cl直到其(部分)转换后的值为零(模8).

Since xor is commutative and associative, we can rewrite this code. Instead of incrementing bl until it matches cl, we will decrement cl until its (partially) transformed value is zero (modulo 8).

    mov   cl,[eax]    ; fetch encrypted byte from memory
X:
    add   dl,2        ; same as in the original loop
    sub   cl,1        ; same as in the original loop
    push  ecx
    xor   ecx,edx     ; transform cl with the current value of dl
    and   cl,7        ; only consider the 3 least significant bits
    pop   ecx         ; restore cl (without clobbering flags)
    jg    X           ; if equal, then we found the right starting point

对于其余的代码,可以保持原样.在[eax]涉及之前,它主要是edx的计算的初始部分.

As for the rest of the code, that can stay as it is. It is mainly the initial part of the calculation of edx, before [eax] becomes involved.

这是完整的解决方案:

encryptL:
    push  eax
    xchg  eax, ecx
    neg   al
    inc   eax
    rol   al, 1
    rol   al, 1
    mov   ebx, eax
    pop   eax
    push  ebx
    pop   edx

    movzx ecx, [eax]
    push  ecx
X:
    add   dl,2
    sub   cl,1
    push  ecx
    xor   ecx,edx
    and   cl,7
    pop   ecx
    jg    X

    pop   ecx
    xor   ecx,edx
    xor   cl,0x96
    rol   cl,1
    mov   [eax],cl
    ret

免责声明:我没有对其进行测试,因此很有可能无法正常工作.我将把调试工作留给您.

Disclaimer: I did not test it, so it's quite likely it will not work. I will leave the debugging up to you.

这篇关于我将如何使其解密而不是加密?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆