selph
selph
发布于 2022-01-16 / 345 阅读
0
0

《xchg rax,rax》片段分析0x0f--CBC异或加解密

前言

本次是该系列的的第0x0f篇,依然是两种等价运算


实验环境:

  • Windows10 + VS2022 + masm

0x0f

代码片段链接:xorpd | xchg rax,rax 0x0f

.loop:
    xor      byte [rsi],al
    lodsb
    loop     .loop

代码分析

lodsb指令:按字节载入rsi(esi)寄存器到al,然后根据方向标志位移动si指针一位

这里进行的操作是一个循环,循环里不断进行异或操作,数据存在rsi里,测试之前需要获取一下数据长度到rcx里,作为loop的循环计数使用,这里的加密操作如下:

rsi[0] ^= al
rsi[1] ^= rsi[0]
rsi[2] ^= rsi[1]
rsi[3] ^= rsi[2]
...

除了第一个字节之外,接下来每一个字节都与前一个字节进行异或操作,属于一种简单的CBC加密

因为异或操作可逆,所以这个加密可解,只需要把原来的加密流程给倒转过来

...
rsi[3] ^= rsi[2]
rsi[2] ^= rsi[1]
rsi[1] ^= rsi[0]
rsi[0] ^= al

具体加解密操作见如下代码

测试代码:

.data
testStr db "abcde123",0

.code
main proc

    ;获取字符串长度
    lea rsi, qword ptr [testStr]
    xor rcx, rcx
Calcstrlen:
    cmp byte ptr [rsi], 0
    je start
    inc rcx
    inc rsi
    jmp Calcstrlen

start:
    ;==========加密操作==========
    lea rsi, qword ptr [testStr]
    lea rax, [020h]

    ;对数据进行逐字节异或加密操作
loop1:
    xor      byte ptr [rsi],al  ;使用al异或一个字节(第一次的时候使用初始的al)
    lodsb                       ;将刚刚异或过的那个字节存到al,然后rsi指向下一个字节
    loop     loop1              ;循环


    ;==========解密操作==========
    ;修改eflags标志位DF方向标志
    pushfq
    or qword ptr [rsp], 010000000000b
    popfq
    ;从最后一个字节开始向前解密操作
    dec rsi
    ;数据处理长度
    mov rcx, 7
loop2:
    mov      al, byte ptr [rsi-1]
    xor      byte ptr [rsi], al
    lodsb
    loop     loop2
    
    lea rax, [020h]
    xor byte ptr [rsi], al

	ret
main ENDP
END

评论