32位程序调用64位函数原理
32位程序调用64位函数
首先,先从宏观分析一下,32位程序的运行需要软硬件两个大方面的支持:
1)硬件上,CPU的解码模式需要是32位模式。64位CPU(我只熟悉INTEL的)是通过GDT表中CS段所对应的表项中L标志位来确定当前解码模式的。这里不展开描述GDT表与CPU运行模式的关系
2)软件上,操作系统需要提供32位的用户态运行时环境(C库,WINDOWS API)对32位程序支持,其次因为win64内核是64位模式的,所以32位运行时环境在与64位内核交互时需要有状态转换。
1.模式切换
参考看雪文章https://bbs.pediy.com/thread-221236.htm
32位模式切换为64位模式 借助retf将CS寄存器从0x23设置为0x33。
retf 远返回指令。当它执行时,处理器先从栈中弹出一个字到IP,再弹出一个字到CS。
$表示当前地址,call $+5表示,调用用 本地址+5字节后的 子程序
2.查找目标函数地址
思想是 目标函数从动态库(ntdll)中获得,我们需要从LDR中匹配动态库,LDR可以在PEB中找到,PEB可以在TEB中找到,WOW64进程中的R12寄存器指向其64位的TEB结构(线程环境块),所以TEB可以通过R12寄存器获得。
找到模块基地址以后,我们就可以通过PE文件结构去获得我们需要的函数了
具体实现参考这里https://b0ldfrev.gitbook.io/note/windows_operating_system/windows-xia-tong-yong-shellcode-yuan-li,只是PE文件从32到32+,要做部分修改。
3.自实现传参
我们得到函数地址以后,不能直接调用 需要通过X64Call执行。 X64调用约定前4个参数通过rcx,rdx,r8,r9来传递,之后通过堆栈传递。
Last updated