目录
笔记
64位恶意代码的必要性:1.在64位操作系统中内核代码是64位的,以64位系统为目标的rootkit(Rootkit通过加载特殊的驱动,修改系统内核,进而达到隐藏信息的目的)必须编译成64位机器码
2.插件和注入代码必须是64位的,以便在64位进程中运行。
3.shellocde作为漏洞利用的一部分
X64架构上的差别:1.指针和地址都是64位的
2.通用寄存器RAX,RBX,RCX
3.一些通用寄存器通过添加L后缀到它们的16位版本,例如对于RBP,BP访问的是低16位,BPL访问的是低8位
4.RIP是64位指令指针
5.新加了R8-R15新的寄存器。其中R8D访问32位,R8W访问16位,R8L访问8位
6.X64可以进行RIP-相对寻址
X32上的绝对寻址
X64上的相对寻址,与位置无关。(将数据地址作为一个相对当前指针的偏移进行存储)
减少了DLL被加载时必须被重定向地址的数量。指针相对寻址也使编写shellcode变得容易,消除了获取指向EIP指针来访问数据的必要。
X64调用约定的差别:与fastcall调用约定相近。调用的前4个参数使用RCX,RDX,R8,R9
叶子函数:没有调用其他函数
非叶子函数:调用了其他函数,在调用另一个函数时,要求分配0x20个字节空间,如果需要并存储寄存器参数。
在这两种函数中,栈空间的改变只可能在函数的开头和结尾
X64栈使用上的差别:在X64的函数中间不能分配任何空间,不在函数中间改变栈的空间大小(带来的问题,没有push,无法确定一个函数有几个参数)
64位汇编代码在函数的开头和末尾都有良好的分节。在开头部分都是传递这个函数的参数。从栈上分配了0x20字节作为存储参数的地方。
X64异常处理:结构化异常处理使用一个存储在PE文件中的静态异常信息表,并且不在栈上存储任何数据。
64位上的32位:在分析一个64位系统上的32位恶意代码时,如果写入的文件路径是Windows/System32,那么应该去Windows/WOW64中去找。对于注册表也一样,Software会重定向到Software/Wow6432Node中。
IsWow64Process函-->判读是否在WOW64进程中
在32位反汇编代码中,只可以得到压入了两个参数
在64位反汇编代码中,可以看出来rdx存储的一个64位的指针,ecx存储一个32位的数据。
实验
Lab21-1
这里main函数有三个参数,argc是一个32位整数,而argv和envp是64位的。跟入main
main
在开始部分,将大量数据压入到栈上,这里吧ocl.exe字节存储到栈上。
这里将程序名与rcx对比,这里用windbg调试一下,打印出处rcx的值为jzm.exe.
接下来一系列网络函数connect,htons,WSAStarup
一个关键函数,跟入sub_140001000
sub_140001000
CreateProcessA有10个参数,而红框的位置是对结构体StartupInfo的赋值。然而物理结构体赋值函参数都是存储到栈上,并且都复杂交织。这里创建了一个反向shell到远程计算机。
Lab21-2
包含了3个资源节,每个资源节都对应一个PE文件
告诉代码是否在一个64位操作系统上以32位进程的方式运行
获取IsWow64Process函数的句柄
获取字节的pid,然后调用IsWow64Process函数。之后分为两条执行路径,一个是32位,一个是64位
X86代码路径:
其中sub_401000是从资源节中提取一个PE结构,之后调用sub_401130
sub_401130
改变权限,
sub_401000是一个从资源节读取PE文件的函数
匹配explorer.exe
这是一个进程注入,将Lab21-02.dll注入到explorer.exe
X64代码路径:
从资源段中读取两个PE文件。
执行Lab21-02.exe文件
而Lab21-02.exe是一个64位的程序,也是一个dll注入函数