能力值:
( LV2,RANK:10 )
|
-
-
2 楼
返回指令就是ret
返回之前会平衡堆栈的 返回的地址就是你CALL之前压入的地址了
|
能力值:
( LV8,RANK:130 )
|
-
-
3 楼
[QUOTE=h辉;1355674]64位 call qword ptr [********]
的流程是怎样的
push rip
jmp call qword ptr [********]
像上面这样?? 好像不对
对应的返回指令是什么
ret ? retf ?
好像都不对[/QUOTE]
rip?是打错了么?EIP?
jmp 和call 还能一起用?
你的意思是call 的含义么?
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
楼主的意思应该是
call可以理解为
先 push eip
再 jmp qword ptr
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
32位汇编区分近跳转和远跳转... 64位下取消了吗
call 指令
CPU 执行call指令时,进行两步操作:
(1)当前的IP或CS和IP压入栈中;
(2)转移
call 指令不能实现短转移 3.依据位移进行转移的call指令
call 标号(将当前的IP压栈后 , 转到标号处执行指令)
CPU执行此种格式的call指令时,进行如下操作:
(1)(sp)= (sp)- 2
((ss)* 16 + (sp))= (IP)
(2)(IP)=(IP)+16位位移 4.前面的 call 指令,其对应的机器指令并没有转移的目的地址,而是相对于当前IP的转移位移。
“ call far ptr ”实现的是段间转移 5.转移地址在寄存器中的call指令
指令格式:call 16位reg
功能:
(sp) = (sp) + 2
((ss)*16+(sp))=(IP)
(IP)=(16位reg)
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
64用syscall试试,如果成功了,麻烦说一下,一直没空试这个
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
其实 你用OD随便载入一个稍微大点的软件,一会儿就明白 近距离和远距离的调用区别。主要是二进制指令不一样。授人与鱼,不如与渔。
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
当初我也是满怀期待打开 OD 的....:结果 . 64 位你懂的
我还是拿 CE 调试看看 就是不如 OD 方便
|
能力值:
( LV13,RANK:460 )
|
-
-
9 楼
[QUOTE=h辉;1355674]64位 call qword ptr [********]
的流程是怎样的
push rip
jmp qword ptr [********]
像上面这样?? 好像不对
对应的返回指令是什么
ret ? retf ?
好像都不对[/QUOTE]
rip 是 x64 体系结构下的扩展指令指针寄存器(eip)
用户汇编代码不能直接读写EIP的内容,除非使用运行在ring0 级别的调试器或内核调试器
但是在执行 call指令前,它会隐式地将EIP中的值(call指令所在地址的下一条指令的地址)作为返回地址压到栈内存上.
通常位于[ebp+4] 处就是返回地址,你可以尝试读取这个栈地址中的内容来提取返回地址
x64 体系结构下的返回指令即ret,(有些编译器生成 retn)它与call成对出现,通常情况下,被调函数在返回主调函数前的最后一条指令就是ret,
ret的内幕是从当前栈顶提取返回地址,保存到EIP中,CPU执行EIP中指向的地址处的指令,如此就实现了将控制权转交主调函数.
|
能力值:
( LV2,RANK:10 )
|
-
-
10 楼
inter 下 IP 好像是不可以直接修改的吧
另 64位 调用函数类似于 FastCall
64位下 长跳的实现为
JUMP
FF 25 (4Byte Offset)
例
jmp offset 0
:address ; qword
CALL
FF 15 (4Byte Offset)
例
CALL offset 0
:address ; qword
详细见 64位 shadowSSDT 360驱动HOOK win32k 实现方式
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
64位下调用协议只有一种,具体名字想不起来了 名字不是 FASTCALL
协议如下:
前四个整型或指针类型参数由RCX,RDX,R8,R9依次传递,前四个浮点类型参数由XMM0,XMM1,XMM2,XMM3依次传递。
调用函数为前四个参数在调用栈上保留相应的空间,称作shadow space或spill slot。即使被调用方没有或小于4个参数,调用函数仍然保留那么多的栈空间,这有助于在某些特殊情况下简化调用约定。
除前四个参数以外的任何其他参数通过栈来传递,从右至左依次入栈。
由调用函数负责清理调用栈。
小于等于64位的整型或指针类型返回值由RAX传递。
浮点返回值由XMM0传递。
更大的返回值(比如结构体),由调用方在栈上分配空间,并有RCX持有该空间的指针并传递给被调用函数,因此整型参数使用的寄存器依次右移一格,实际只可以利用3个寄存器,其余参数入栈。函数调用结束后,RAX返回该空间的指针。
除RCX,RDX,R8,R9以外,RAX、R10、R11、XMM4 和 XMM5也是易变化的(volatile)寄存器。
RBX, RBP, RDI, RSI, R12, R14, R14, and R15寄存器则必须在使用时进行保护。
在寄存器中,所有参数都是右对齐的。小于64位的参数并不进行高位零扩展,也就是高位是无法预测的垃圾数据。
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
没搜索到..求链接
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
64 位 syscall 和32位差不多吧...
我在学64位的驱动.. 好像用不到这个
|
能力值:
( LV2,RANK:10 )
|
-
-
14 楼
调用协议类似 __fastcall 但好像不叫__fastcall,具体叫什么忘记了,好早以前看过,你看看微软官方介绍
和inter x64 指令集 相关 助记符 说明
打开 PCHunter->内核钩子->ShadowSSDT 下,如果安装360
就会发现被Hook函数查看被挂钩函数字节码,跟几步,可以看到如何实现的.
FF 25 00 00 00 00(4Byte Offset) 8 byte (8Byte MemAddr)
{具体过程 建议你自己从代码里面跟一下就明白了}
调用协议参考
前四个整型或指针类型参数由RCX,RDX,R8,R9依次传递,前四个浮点类型参数由XMM0,XMM1,XMM2,XMM3依次传递。
调用函数为前四个参数在调用栈上保留相应的空间,称作shadow space或spill slot。即使被调用方没有或小于4个参数,调用函数仍然保留那么多的栈空间,这有助于在某些特殊情况下简化调用约定。
除前四个参数以外的任何其他参数通过栈来传递,从右至左依次入栈。
由调用函数负责清理调用栈。
小于等于64位的整型或指针类型返回值由RAX传递。
浮点返回值由XMM0传递。
更大的返回值(比如结构体),由调用方在栈上分配空间,并有RCX持有该空间的指针并传递给被调用函数,因此整型参数使用的寄存器依次右移一格,实际只可以利用3个寄存器,其余参数入栈。函数调用结束后,RAX返回该空间的指针。
除RCX,RDX,R8,R9以外,RAX、R10、R11、XMM4 和 XMM5也是易变化的(volatile)寄存器。
RBX, RBP, RDI, RSI, R12, R14, R14, and R15寄存器则必须在使用时进行保护。
在寄存器中,所有参数都是右对齐的。小于64位的参数并不进行高位零扩展,也就是高位是无法预测的垃圾数据。
64位程序调用,所有的函数地址都在一段表里面,Offset指向表地址
|
能力值:
( LV2,RANK:10 )
|
-
-
15 楼
FF 25 00 00 00 00(4Byte Offset) 8 byte (8Byte MemAddr)
这种 HOOK 方式已经实现了。。
现在就是纠结
FF 15 00 00 00 00(4Byte Offset) 8 byte (8Byte MemAddr)
call qword ptr [********]
这是 HOOK NtOpenProcess 之后 代理函数中
asm volatile(
"add qword ptr [rbp+8], 0xE;" // 跳过hook处被覆盖的代码
"leave;" // 平衡代理函数头中的 enter 指令
"sub rsp, 0x38;"
"mov rax, gs:0x188;"
"mov r10b, [rax+0x1F6];"
"ret;" // 返回继续执行
);
用ret 方式跳转回去就蓝屏 改成retf 也是蓝屏...
图中是用 FF 25 00 00 00 00(4Byte Offset) 8 byte (8Byte MemAddr) 方式 hook 并 jmp 回去跳过hook处被覆盖的代码 代理函数 可以正常hook
|
能力值:
( LV2,RANK:10 )
|
-
-
16 楼
定义个一样的函数接口就行啊,找到函数头
NTSTATUS MyZwOpenProcess(
_Out_ PHANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_opt_ PCLIENT_ID ClientId
)
{
return pfZwOpenProcess(ProcessHandle,DesiredAccess, ObjectAttributes,ClientId);
}
save (2 + 4 + 8) + 破坏的字节
jmp 到 address + Offset
NtOpenProcess 的头部修改为 MyZwOpenProcess
pfZwOpenProcess = save 的地址
和32位下 jmp inline hook 没什么区别啊
你看看 360是如何hook 的
|
能力值:
( LV2,RANK:10 )
|
-
-
17 楼
64位下为了减少指令长度,call用的是相对地址。
|
能力值:
( LV3,RANK:20 )
|
-
-
18 楼
RIP 是64位下的IP寄存器名字
EIP->RIP
EAX->RAX
EBX->RBX
以此类推。。。
|
能力值:
( LV8,RANK:130 )
|
-
-
19 楼
谢谢。平时不怎么整x64的。
|
能力值:
( LV9,RANK:140 )
|
-
-
20 楼
x64 下 的call far 字节码是怎样的
|
|
|