TEA Encryption, сборка внедрения - PullRequest
0 голосов
/ 05 апреля 2020

Поскольку я пытаюсь улучшить свои навыки сборки x86, я разрабатываю реализацию NASM Tiny Encryption Algorithm (TEA) .

Алгоритм шифрования определяется следующим образом:

void encrypt (uint32_t v[2], uint32_t k[4]) {
    uint32_t v0=v[0], v1=v[1], sum=0, i;           /* set up */
    uint32_t delta=0x9E3779B9;                     /* a key schedule constant */
    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */
    for (i=0; i<32; i++) {                         /* basic cycle start */
        sum += delta;
        v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
        v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
    }                                              /* end cycle */
    v[0]=v0; v[1]=v1;
}

К сожалению, моя версия NASM где-то не работает, и до сих пор я не смог найти ошибки.

Реализация NASM была разработана под * nix x86 и должен быть связан со следующей командой, поскольку я непосредственно пишу в секции .text во время выполнения: ld -m elf_i386 -N -o tea tea.nasm

Здесь мой код до сих пор:

global _start
; EAX = store arithmetic results
; ECX = COUNTER
; EBX = current chunk (v0,v1)
; EDX = sum
; ESI = *encrypted_shellcode
; EDI = *key
section .text
_start:
    jmp short key_section               ; goto key_section

key_section:
    ; key0: 0x6c645a37
    ; key1: 0x6e775667
    ; key2: 0x57433641
    ; key3: 0x4e6c7151
    call key_loader                 ; goto key_loader, putting key on the stack
    ;       |          0          |            1           |           2          |            3           |
    ;       |         EDI         |          EDI+4         |         EDI+8        |          EDI+12        |
    key: db 0x6c, 0x64, 0x5a, 0x37, 0x6e, 0x77, 0x56, 0x67, 0x57, 0x43, 0x36, 0x41, 0x4e, 0x6c, 0x71, 0x51

key_loader:
    pop edi                             ; load address of our key into EDI (JMP CALL POP trick)
    jmp short shellcode_section         ; goto shellcode_section

encoder:                                ; encoder
    pop esi                             ; load address of our shellcode into ESI (JMP CALL POP trick)
    mov ecx, 3                          ; load the number of our shellcode chunks, used to loop. (shellcode length is 24. 24/4(DWORD)=6 blocks/2(chunks taken 2by 2)=3)
    ;cld                                ; clear direction flag, setting it to 0. 

encrypt_loop:
    push ecx                            ; save counter status before entering 32 iteration loop
    mov ecx, 32                         ; store loop counter, we nedd to cycle x32 times
    xor edx, edx                        ; clean EDX (sum), EDX = 0
    loop_32:
        mov ebx, dword [esi+4]          ; v1 load encrypted_shellcode's chunk DWORD pointed by ESI in EBX | EBX=B
        ; sum = sum+delta
        add edx, 0x9E3779B9             ; sum = sum+delta
        ; v0 = v0 + ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
        mov eax, ebx                    ; v1 is now in EAX
        shl eax, 4                      ; v1<<4
        add eax, dword [edi]            ; +k0
        push eax                        ; store EAX (result) on stack
        mov eax, ebx                    ; v1 is now in EAX
        add eax, edx                    ; v1 + sum
        push eax                        ; store EAX (result) on stack
        mov eax, ebx                    ; v1 is now in EAX
        shr eax, 5                      ; v1>>5
        add eax, dword [edi+4]          ; +k1
        ; EAX = ((v1>>5) + k1)
        pop ebx                         ; restore EBX = (v1 + sum)
        xor eax, ebx                    ; EAX = (v1 + sum) ^ ((v1>>5) + k1)
        pop ebx                         ; restore EBX = (v1<<4) + k0)
        xor eax, ebx                    ; EAX = ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1)
        add eax, dword [esi]            ; v0 = v0 + ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1)
        mov dword [esi], eax            ; store encrypted v0 back to shellcode "buffer"
        ;--------------------------------------------------------------------------------------
        mov ebx, dword [esi]            ; v0 load shellcode's chunk DWORD pointed by ESI in EBX | EBX=A
        ; v1 = v1 + ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
        mov eax, ebx                    ; v0 is now in EAX
        shl eax, 4                      ; v0<<4
        add eax, dword [edi+8]          ; +k2
        push eax                        ; store EAX (result) on stack
        mov eax, ebx                    ; v0 is now in EAX
        add eax, edx                    ; v0 + sum
        push eax                        ; store EAX (result) on stack
        mov eax, ebx                    ; v0 is now in EAX
        shr eax, 5                      ; v0>>5
        add eax, dword [edi+12]         ; +k3
        ; EAX = ((v0>>5) + k3)
        pop ebx                         ; restore EBX = (v0 + sum)
        xor eax, ebx                    ; EAX = (v0 + sum) ^ ((v0>>5) + k3)
        pop ebx                         ; restore EBX = (v0<<4) + k2)
        xor eax, ebx                    ; EAX = ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3)
        add eax, dword [esi+4]          ; v1 = v1 + ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3)
        mov dword [esi+4], eax          ; store encrypted v1 back to shellcode "buffer"
        loop loop_32                    ; ECX is 0? No, we go back at loop_32 and execute the cicle again
    pop ecx                             ; restore ECX counter status
    add esi, 8                          ; select next chunk "couple"                
    loop encrypt_loop                   ; ECX is 0? No, we go back at decrypt_loop and execute the cicle again
    exec:
    int3                                ; ECX is 0! We've encrypted our shellcode. GDB: x/24cb encrypted_shellcode

shellcode_section:
        call encoder                    ; goto decoder, putting shellcode on the stack
        ;                       |          A          |           B           |           C           |           D            |          E           |            F          |
        ;                       |         ESI         |         ESI+4         |         ESI+8         |         ESI+12         |        ESI+16        |          ESI+20       |
        encrypted_shellcode: db 0x31, 0xc0, 0x50, 0x68, 0x2f, 0x2f, 0x73, 0x68, 0x68, 0x2f, 0x62, 0x69, 0x6e, 0x87, 0xe3, 0xb0, 0x0b, 0xcd, 0x80, 0x90, 0x90, 0x90, 0x90, 0x90
        ;                       |<-chunk read direction| 

C реализация работает правильно (может шифровать / дешифровать) и возвращает следующее:

  • Оригинал v0 0x31c05068
  • Оригинал v1 0x2f2f7368
  • k0 = 0x6c645a37, k1 = 0x6e775667 , k2 = 0x57433641, k3 = 0x4e6c7151

C:

  • Crypted v0: 0x17c59b4a
  • Crypted v1: 0xf8c4497

ASM:

  • Crypted v0: 0x56efe51
  • Crypted v1: 0xba4731 e3

Почему моя реализация не работает? Чего мне не хватает?

Спасибо всем заранее и, пожалуйста, будьте добры, я не эксперт

...