尾部跳转的方法
1.push+ret
2.call jmp
global _start
_start:
jmp short getdata ; 跳转到getdata
begin:
pop ebx ; 弹出shellcode的地址
xor ecx,ecx ; 清零循环计数器ecx
sub cx, -0x15F ; 设置cx为shellcode长度
decode:
xor byte [ebx], 0x99 ; 异或key来解码
inc ebx ; 进入下一字节
loop decode ; 循环解码
jmp short shellcode ; 跳到解码完成的shellcode
getdata:
call begin ; 将下一条指令(shellcode)位置压栈,跳到begin
shellcode: ; 异或加密后的shellcode
db ..........................
利用call{
pop ebx
}
shellcode。
ebx获取shellcode地址。
3.NtContinue/ZwContinue
NtContinue:
ntdll!ZwContinue 采用与 ntdll!NtContinue 相同的参数。
NtContinue(
IN PCONTEXT ThreadContext;
IN BOOLEAN RaiseAlert
);
NtContinue会将CONTEXT结构体的eip 设置为线程真正的起始执行入口。
ZwContinue:
ZwContinue (
IN PCONTEXT ThreadContext;
IN BOOLEAN RaiseAlert
);
ZwContinue的作用是继续执行一个线程,它的一个参数是CONTEXT指针,找到Context->EIP,下断就可以跟踪,否则F8后程序挂掉。