5.4.3 解码汇编

“清楚了编码方法后,解码思想也就很容易理解了。解码就是判断enShellCode的每个字符,如果不是‘0’,就直接异或Key恢复回去;如果是‘0’,就把后面的那个字符减去‘0’再异或Key,这样就可恢复以前的ShellCode。”老师说得很快,“我们边看代码边理解思路吧!”

老师打出如下的解码汇编exchangeDecode.cpp:

jmp decode_end
decode_start:
pop edi
push edi
pop esi
xor ecx,ecx 
mov ecx,0x101 //要解码个数
Decode_loop: 
Lodsb //[esi] -> eax
cmp al,0x30 //判断是否为标志‘0’
jz special_char_clean //如果是,就跳去特殊字符处理
store: //保存
xor al, 0x97 //异或KEY = 0x97
stosb //保存解码后的ShellCode
loop Decode_loop
jmp decode_ok
special_char_clean: //特殊字符处理
lodsb //读后一位字符
sub al,0x31 //把后一位字符减去0x31,就恢复原来的值
jmp store 
decode_end: 
call decode_start
decode_ok: //其余真正加密的Shellcode代码会连接在此处

“首先还是一样,”老师说道,“如下代码是定位enShellCode位置。在前面异或大法里讲过,大家翻翻笔记就清楚了。”

jmp decode_end
decode_start:
pop edi
……
……
decode_end:
call decode_start

“接下来的代码是把解码的个数赋给ecx,解码一个字节,ecx就减1,直至ecx减为0,就表示解码结束了,跳到还原后的ShellCode中执行。”

xor ecx,ecx 
mov ecx,0x101 //要解码个数

“然后,如下代码用于判断是否为标志,如果是,就不管标志,去处理后面一个字符—-减去0x31,恢复原来的值。”

cmp al,0x30 //判断是否为标志
jz special_char_clean //如果是,就跳去特殊字符处理
……
special_char_clean: //特殊字符处理
lodsb //读后一位字符
sub al,0x31 //把后一位字符减去0x31,就恢复原来的值

“最后,如下代码就是异或Key,恢复成原来的ShellCode并保存。”

xor al, 0x97 //异或KEY = 0x97
stosb //保存解码后的ShellCode

“读程序,一定要带着思路去理解。”老师再次强调。

“嗯,我现在清楚了!”宇强对小倩说。

“好了,我们用直接替换法来对开DOS窗口的程序进行变形,看看编码程序和解码程序是如何使用的!”老师说道。