有了这个“加密”功能,我该如何反转它并编写一个解密功能?

时间:2018-07-04 12:26:02

标签: assembly x86

TL; DR-第一个代码只是显示在实际开始执行操作之前发生的事情。看第二个代码,这是我的ASM对字符串进行加密的操作。查看第三个框,它显示结果。 Ekey = h。 (总体代码由C ++和内联汇编组成)

如何再次将其反转,使其回到“父级”(加密之前的原始状态)。


所以我得到了一个汇编代码,该代码对给定的字符串进行加密((主体用C ++编写,简单的cin和couts + for循环循环每个字符,没什么大不了的,但是问题适用于汇编)

这是进入加密例程之前发生的事情:(不同的功能)

push   eax              // Push EAX(Ekey) value to the stack
push   ecx              // Push ECX(character to be encrypted) value to the stack

movzx  ecx, temp_char   // Copies the contents of the temp_char to the ECX register and zero extends the value.
lea    eax, EKey        // Load the address of EKey, into EAX
call   encrypt          // pushes the return address onto the stack and transfers control to a calling label(In this case, it's encrypt). 
mov    temp_char, al    // Copy AL into temp_char variable.

pop    ecx              // Get value from the top of the stack into ECX.
pop    eax              // EAX, gets value from the top of the stack.

我的加密例程如下:澄清一下,评论是我的。它们很有可能是正确的,或者其中一些可能是错误的。(对不起,我还在学习中)

        push  ebp                      // Save the old base pointer value.                           
        mov   ebp, esp                 // esp; Set the new base pointer value.                       
        sub   esp, 12                  // Make room for 3 registers          
        push ebx                       // Push EBX value to the stack
        push edx                       // Push EDX value to the stack
        push ecx                       // Push ECX(character to be encrypted) value to the stack
        movzx edx, byte ptr[eax]       // Taking first byte from EAX(Ekey), zero-extending it with 0's , moving that into EDX
        and edx, 0x43                  // Starting from the most significant bit. EDX will be set to 0x00(zeroed out) if 2nd, 7th and 8th bits are 0's. Otherwise if any bits are 1 within the mask, the resulting value will be non-zero

        cmp edx, 0x00                  // See if EDX is equal to 0.
        jnz x16                        // If EDX != 0 go to X16.
        mov edx, 0x07                  // If EDX will be equal to 0, set EDX value to 0x07..
        x16:        inc dl             // Add one to the 'DL' register. Character variable moves up // DL is 1st byte of EDX.
        mov dword ptr[eax], edx        // dword 4 bytes, EDX value into EAX(Ekey) and zero extend it to 4 bytes.
        pop ebx                        // Getting value from the top of the stack, and storing it in the EBX.
        y16 : dec ebx                  // Decrement EBX by 1.
        dec edx                        // Decrement EDX by 1.
        jnz y16                        // If EDX != 0 go to Y16.
        not bl                         // Reverse contents of BL. Such as., (Before 0101, after 1010.) <- Example. So given input will be revesed for encryption purposes. BL, is a 1st byte of EBX.

        pop edx                        // Restores original value of EDX
        mov eax, ebx                   // Move contents from EBX register into EAX(Ekey) register.
        pop ebx                        // Get value from the top of the stack, and then store it in EBX. EAX(Ekey) => EBX.              
        mov  esp, ebp                  // Deallocate local variables                                 
        pop  ebp                       // Restore the caller's base pointer value                    
        ret                            // Gets address from the top of the stack(In this case it's EBX) and returns the value as result. Returning the final result.

这就是“ soon”字符串的作用

 Date: 04/07/2018  Time: 13:53:36

Original string =  soon Hex = 73  6f  6f  6e  

Encrypted string = ÍÒÓÕ Hex = cd  d2  d3  d5  

我花了很多时间来解决这个问题,以使其“逆转”,但是我没想到有什么大不了的。最终结果是我缺少一个键盘。尽管我没有成功,但我已经在互联网上查找了如何实现此目标的方法(包括stackoverflow)。所以这是我在这里的最后选择。

如何反转这些说明以将其恢复为原始字符串?

1 个答案:

答案 0 :(得分:2)

这是您程序的C版本;我认为它很明显是如何工作的:

#include <libc.h>
int ec(unsigned char *s, int c) {
    unsigned char y;
    y = *s & 0x43;
    if (y == 0) {
        y = 7;
    }
/*-
  NB: y is in { 7,1,2,3,64,65,66,67 }
*/
    *s = ++y;
    c -= y;
    return ~c & 0xff;
}

void estr(char *s) {
    unsigned char k;
    k = 'h';
    while (*s) {
        *s = ec(&k, *s);
        s++;
    }
}

int main() {
    char p[20];
    strcpy(p, "Hello, world!");
    printf("%s\n", p);
    estr(p);
    printf("%s\n", p);
    estr(p);
    printf("%s\n", p);
}

这里有两件事发生;首先是按键顺序。键从给定的种子值('H'= 0x48)开始。通过操作键=(键AND 0x43)+1生成序列:0x41,0x42,0x43,0x44,0x41,....请注意代码中0的怪异异常。

此序列通过加密功能应用于每个字符:c = NOT(c-密钥)。此函数是其自身的逆函数,因此,如果将其应用于纯文本,则会生成加密的文本,反之亦然。

我希望有帮助。

相关问题