前言
本次是该系列的的第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