Шифрование сборки x86 для расшифровки - PullRequest
0 голосов
/ 21 марта 2020

Итак, я пытаюсь создать расшифровку из процедуры шифрования, но у меня действительно плохой опыт работы с ней. Кто-нибудь может мне помочь, пожалуйста! Заранее спасибо!

PS. рутина плохо написана намеренно, чтобы потом мы могли ее изменить. отредактировано: извините, вот вся моя процедура шифрования, все, что я знаю, это то, что все, что сделано с моим EKey (eax), должно остаться прежним, но мне нужно полностью изменить то, что сделано с char (ecx). Я действительно не знаю, с чего начать, еще раз спасибо заранее.

char EKey = 'z';      //unique key:z

#define StudentName "asdasd"
#define MAXCHARS 6    // Max user input

using namespace std;
#include <string>               // for strings
#include <fstream>              // file I/O
#include <iostream>             // for cin >> and cout <<
#include <iomanip>              // for fancy output
#include "TimeUtils.h"          // for GetTime, GetDate, etc.

#define dollarchar '$'          // string terminator

char OChars[MAXCHARS] = { 'S','O','S','I','G',' ' },     // Original character string
EChars[MAXCHARS],                                        // Encrypted character string
DChars[MAXCHARS] = "Soon!";                              // Decrypted character string

//----------------------------- C++ Functions ----------------------------------------------------------

void get_char(char& a_character)
{
    a_character = (char)_getwche();
    if (a_character == '\r' || a_character == '\n')  // allow the enter key to work as the terminating character too
        a_character = dollarchar;
}
//-------------------------------------------------------------------------------------------------------------

void get_original_chars(int& length)
{
    char next_char = ' ';
    length = 0;
    get_char(next_char);

    while ((length < MAXCHARS) && (next_char != dollarchar))
    {
        OChars[length++] = next_char;
        get_char(next_char);
    }
}

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

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

        __asm
        {
            push   eax                          //saves EKey to the memory stack w/ a value of 0
            push   ecx                          //saves Char to the memory stack w/ a value of 83
            push   edx                          //saves EKey to the memory stack w/ a value of 1

            movzx  ecx, temp_char               //moves my character value (8 bit) to ecx (32 bit) w/ 0 extension which is 'S' and continues until the last character of my string. 

            lea    eax, EKey                    //lea (loads effective address) puts the memory address of EKey to eax 
            push   ecx                          //saves Char to the memory stack w/ a value of 83
            push   eax                          //saves Char to the memory stack w/ a value of 5241440

            call   encrypt_3                    //calls a function in this case my unique encryption routine  
            add    esp, 8                       //adds a value of 8 to the stack pointer, esp= 5241176 + 8 
            mov    temp_char, dl                //copies the value of the encrypted Char to the current Char

            pop    edx                          //removes the encrypted char from the stack memory 
            pop    ecx                          //removes the char from the stack memory   
            pop    eax                          //removes the  EKey from the stack memory
        }
        EChars[i] = temp_char;                  // Store encrypted char in the Encrypted Chars array
    }
    return;

    __asm
    {
    encrypt_3:
        push ebp                                //saves ebp to the stack memory
            mov ebp, esp                        //copies the value of esp to ebp
            mov eax, [ebp + 8]                  //adds 8 to the value of ebp then copy its value to EKey
            mov ecx, [ebp + 12]                 //adds 12 to the value of ebp (recently added 8) then copy the value to the encrypted character
            push  edx                           //puts the edx to the stack memory  
            push  ecx                           //puts CHAR to the stack memory
            push  eax                           //puts EKey to the stack memory
            movzx eax, byte ptr[eax]            //Uses the EKey (z) inside eax as the eax memory address 
            rol   al, 1                         //rotate al by 1 bit to the left, 111 1010‬ (moves the 0 at the end to the beginning)
            not al                              //invert each bit of al (1111 0100‬) becomes 0000 1011
            rol   al, 1                         //rotates the inverted binary of al to the left by 1 bit 
            rol   al, 1                         //rotates al binary by 1 bit again to the left, 0001 0110‬
            mov   edx, eax                      //copies the value of Ekey to edx, edx = 44
            pop   eax                           //removes the eax register from the stack memory        
            mov   byte ptr[eax], dl             //Uses the value of edx as the byte address of eax (Ekey)
            pop   ecx                           //removes the ecx (EKey) from the stack memory
            xor ecx, edx                        //implements the XOR operation between edx and CHAR, 83 and 44 becomes 127 (111 1111)
            mov   eax, ecx                      //copy the XORed value of Char to EKey
            ror   al, 1                         //rotates al value by 1 bit to the right 127 (0111 1111‬)
            ror   al, 1                         //rotates al value by 1 bit to the right 191 (1011 1111‬)
            ror   al, 1                         //rotates al value by 1 bit to the right 223 (1101 1111‬) al value is now 239 (1110 1111‬)
            pop   edx                           //removes edx from the stack memory 
            mov   edx, eax                      //copy the value of EKey to edx 239 (1110 1111‬)
            pop  ebp                            //removes ebp from the stack memory
            ret                                 //proceeds to the line after the call instruction 
    }
}

//----------------- DECRYPTION ROUTINES -----------------//

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

    for (int i = 0; i < length; i++)            // Decrypt characters one at a time
    {
        temp_char = EChars[i];                  // Get the next char from Encrypted Chars array

        __asm
        {
            push   eax                          //saves EKey to the memory stack w/ a value of 0
            push   ecx                          //saves Char to the memory stack w/ a value of 83

            movzx  ecx, temp_char               //moves my character value (8 bit) to ecx (32 bit) w/ 0 extension which is 'S' and continues until the last character of my string. 

            lea    eax, EKey                    //lea (loads effective address) puts the memory address of EKey to eax 
            push   ecx                          //saves Char to the memory stack w/ a value of 83
            push   eax                          //saves Char to the memory stack w/ a value of 5241440

            call   decrypt_3                    //calls a function in this case my unique encryption routine  
            add    esp, 8                       //adds a value of 8 to the stack pointer, esp= 5241176 + 8 
            mov    temp_char, dl                //copies the value of the encrypted Char to the current Char

            pop    ecx                          //removes the char from the stack memory   
            pop    eax                          //removes the  EKey from the stack memory
        }
        DChars[i] = temp_char;                  // Store decrypted char in the decrypted Chars array
    }
    return;
    __asm
    {
    decrypt_3:
        push ebp                                //saves ebp to the stack memory
            mov   ebp, esp                      //copies the value of esp to ebp
            mov   eax, [ebp + 8]                //adds 8 to the value of ebp then copy its value to EKey
            mov   ecx, [ebp + 12]               //adds 12 to the value of ebp (recently added 8) then copy the value to the encrypted character

            push  edx                           //puts the edx to the stack memory  
            push  ecx                           //puts CHAR to the stack memory
            push  eax                           //puts EKey to the stack memory

            movzx eax, byte ptr[eax]            //Uses the EKey (z) inside eax as the eax memory address 
            rol   al, 1                         //rotate al by 1 bit to the left, 111 1010‬ (moves the 0 at the end to the beginning)
            not al                              //invert each bit of al (1111 0100‬) becomes 0000 1011
            rol   al, 1                         //rotates the inverted binary of al to the left by 1 bit 
            rol   al, 1                         //rotates al binary by 1 bit again to the left, 0001 0110‬
            mov   edx, eax                      //copies the value of Ekey to edx, edx = 44
            pop   eax                           //removes the eax register from the stack memory        
            mov   byte ptr[eax], dl             //Uses the value of edx as the byte address of eax (Ekey)
            pop   ecx                           //removes the ecx (EKey) from the stack memory
            xor ecx, edx                        //implements the XOR operation between edx and CHAR, 83 and 44 becomes 127 (111 1111)
            mov   eax, ecx                      //copy the XORed value of Char to EKey
            ror   al, 1                         //rotates al value by 1 bit to the right 127 (0111 1111‬)
            ror   al, 1                         //rotates al value by 1 bit to the right 191 (1011 1111‬)
            ror   al, 1                         //rotates al value by 1 bit to the right 223 (1101 1111‬) al value is now 239 (1110 1111‬)
            pop   edx                           //removes edx from the stack memory 
            mov   edx, eax                      //copy the value of EKey to edx 239 (1110 1111‬)
            pop   ebp                           //removes ebp from the stack memory
            ret                                 //proceeds to the line after the call instruction 
    }
}

//----------------- end of decrypt_chars function-----------------//




//************ MAIN PROGRAM *************************************************************************************

int main(void)
{
    int char_count(5);  // The number of actual characters entered (upto MAXCHARS limit).

    //cout << "\nPlease enter upto " << MAXCHARS << " alphanumeric characters:  ";
    //get_original_chars (char_count);  // Input the original character string to be encrypted 

    //*****************************************************

    // Open a file to store results (you can view and edit this file in Visual Studio)

    ofstream EDump;
    EDump.open("EncryptDump.txt", ios::app);
    EDump << "\n\nFoCA Encryption program results (" << StudentName << ") Encryption key = '" << EKey << "'";
    EDump << "\nDate: " << GetDate() << "  Time: " << GetTime();

    //*****************************************************
    // Display and save to the EDump file the string just input

    cout << "\n\nOriginal string =  " << OChars << "\tHex = ";
    EDump << "\n\nOriginal string =  " << OChars << "\tHex = ";

    for (int i = 0; i < char_count; i++)
    {
        cout << hex << setw(2) << setfill('0') << ((int(OChars[i])) & 0xFF) << "  ";
        EDump << hex << setw(2) << setfill('0') << ((int(OChars[i])) & 0xFF) << "  ";
    };

    //*****************************************************
    // Encrypt the string and display/save the result

    encrypt_chars(char_count, EKey);

    cout << "\n\nEncrypted string = " << EChars << "\tHex = ";
    EDump << "\n\nEncrypted string = " << EChars << "\tHex = ";
    for (int i = 0; i < char_count; i++)
    {
        cout << ((int(EChars[i])) & 0xFF) << "  ";
        EDump << ((int(EChars[i])) & 0xFF) << "  ";
    }

    //*****************************************************
    // Decrypt the encrypted string and display/save the result

    decrypt_chars(char_count, EKey);    //**** YOU NEED TO WRITE THE BODY OF THIS FUNCTION ***

    cout << "\n\nDecrypted string = " << DChars << "\tHex = ";
    EDump << "\n\nDecrypted string = " << DChars << "\tHex = ";
    for (int i = 0; i < char_count; i++)
    {
        cout << ((int(DChars[i])) & 0xFF) << "  ";
        EDump << ((int(DChars[i])) & 0xFF) << "  ";
    }
    //*****************************************************

    cout << "\n\n\n";
    EDump << "\n\n-------------------------------------------------------------";
    EDump.close();

    system("PAUSE");
    return (0);
} // end of whole encryption/decryption program --------------------------------------------------------------------

1 Ответ

1 голос
/ 21 марта 2020

Я перенес вашу встроенную сборку в 32-разрядный источник NASM и повторно применил внешний l oop (encrypt_chars) в том же источнике на ассемблере. Я загрузил репозиторий с обновлениями и короткую тестовую программу в C, которую можно скомпилировать на Linux с помощью gcc -m32. Для этого вам понадобится NASM, g cc и моя коллекция макросов . Вот источник сборки:

Я создал тестовую программу C, которая заполняет буфер объемом 1 КБ 32-разрядным LFSR, а затем несколько раз пытается кодировать и декодировать данные с помощью различных ключей. В случае неожиданного результата будет отображаться «Ошибка:». Вот источник:

Я сделал тестовый скрипт в bash. По умолчанию используется ../lmacros/ в качестве источника коллекции макросов. Вы можете изменить это (например, запустив NASMINCLUDE=path/to/macros/ ./test.sh), если поместите файлы макроса (lmacros1.mac и lmacros2.mac и lmacros3.mac) в другое место. Вы также можете указать различные флаги для NASM или компилятора C. Это сценарий:

#! /bin/bash

set -e

[ -z "$NASM" ] && NASM=nasm
[ -z "$NASMOPT" ] && NASMOPT="-g"
[ -z "$NASMINCLUDE" ] && NASMINCLUDE=../lmacros/
[ -z "$CC" ] && CC=gcc
[ -z "$CCOPT" ] && CCOPT="-g -O0 -m32"

"$NASM" -felf $NASMOPT test.asm -o test.o -I "$NASMINCLUDE"
"$CC" $CCOPT main.c test.o -o main
./main

Вот как это выглядит, если запустить его, если это удастся:

$ NASM=oldnasm ./test.sh
Test 1 with same key succeeded!
Test 2 with different key did not succeed.
Test 3 with same key succeeded!
Test 4 with different key did not succeed.
$ 

Была только одна конкретная c часть, которую мне пришлось перейдите от функции encrypt_3 к созданию decrypt_3. Расчет ключа остается точно таким же. Нам нужно только изменить, как это значение байта ключа используется для преобразования входного байта в то, что становится выходным байтом. Я цитирую указанную здесь часть c:

%if 0
; xor cl, KEYBYTE
; ror cl, 3
            xor ecx, edx                        ; implements the XOR operation between edx and CHAR, 83 and 44 becomes 127 (111 1111)
            mov   eax, ecx                      ; copy the XORed value of Char to EKey
            ror   al, 1                         ; rotates al value by 1 bit to the right 127 (0111 1111‬)
            ror   al, 1                         ; rotates al value by 1 bit to the right 191 (1011 1111‬)
            ror   al, 1                         ; rotates al value by 1 bit to the right 223 (1101 1111‬) al value is now 239 (1110 1111‬)
%else
; rol cl, 3
; xor cl, KEYBYTE
    rol cl, 3
    xor cl, dl
    mov al, cl
%endif

Я не оптимизировал программу и не обновил ваши комментарии в источнике сборки. Вероятно, вы можете перенести

указанное c решение декодирования во всю программу, оно невелико.
...