我的应用程序(用Delphi编写,但这并不重要)动态生成代码块(它包含一个内置的编译器)。为了让Windows x64上的异常正常工作,我需要通过RtlAddFunctionTable
描述生成的函数。到目前为止,我已经将代码生成器更改为仅使用官方的prolog和epilog表单,并且我已经通过设置包含UNWIND_INFO等的RUNTIME_FUNCTION对它们进行了编码。
但是,生成的代码中的(故意)访问冲突仍会导致应用程序立即终止,因此显然出现了问题。使用windbg
,我看到以下内容(其中0x4c5006f
是异常地址):
0:000> .fnent 0x4c5006f
Debugger function entry 00000000`05436910 for:
BeginAddress = 00000000`00000000
EndAddress = 00000000`00000097
UnwindInfoAddress = 00000000`000000a0
但是,它不会在此下方打印展开信息。我可以从内存窗口看到它:
00000000`04c50000 53 56 57 55 41 54 41 55 41 56 41 57 48 83 ec 08 SVWUATAUAVAWH...
00000000`04c50010 49 89 ce 9b db e3 9b d9 3c 24 41 d9 ae e4 00 00 I.......<$A.....
00000000`04c50020 00 0f ae 5c 24 04 4c 89 f0 0f ae 90 e0 00 00 00 ...\$.L.........
00000000`04c50030 4d 8b be 28 01 00 00 4c 89 fd 49 8b 4f 08 48 85 M..(...L..I.O.H.
00000000`04c50040 c9 0f 84 1d 00 00 00 83 69 f0 01 0f 8f 13 00 00 ........i.......
00000000`04c50050 00 48 89 ca 4c 89 f1 48 83 ec 20 e8 70 41 ba fb .H..L..H.. .pA..
00000000`04c50060 48 83 c4 20 48 33 c9 49 89 4f 08 49 8b 4f 08 48 H.. H3.I.O.I.O.H
00000000`04c50070 3b 09 ba 03 00 00 00 89 51 08 0f ae 54 24 04 9b ;.......Q...T$..
00000000`04c50080 db e2 9b d9 2c 24 48 83 c4 08 41 5f 41 5e 41 5d ....,$H...A_A^A]
00000000`04c50090 41 5c 5d 5f 5e 5b c3 90 90 90 90 90 90 90 90 90 A\]_^[..........
00000000`04c500a0 01 10 09 00 10 02 0c f0 0a e0 08 d0 06 c0 04 50 ...............P
00000000`04c500b0 03 70 02 60 01 30 00 00 00 00 00 00 00 00 00 00
在偏移量4c500a0处,您会看到展开信息(01 10 09 00),然后是与以下序言对应的九个条目:
push rbx
push rsi
push rdi
push rbp
push r12
push r13
push r14
push r15
sub rsp, $8
我将0x4c50000作为基地址传递给RtlAddFunctionTable
。为什么windbg
不打印展开信息?我误解了抵消的运作方式吗?
与常规Delphi函数比较:
0:000> .fnent 0x79caa9
Debugger function entry 00000000`05436910 for:
BeginAddress = 00000000`0039ca70
EndAddress = 00000000`0039caaf
UnwindInfoAddress = 00000000`005304d8
Unwind info at 00000000`009304d8, a bytes
version 1, flags 0, prolog 8, codes 3
frame reg 5, frame offs 0
00: offs 8, unwind op 3, op info 0 UWOP_SET_FPREG
01: offs 5, unwind op 2, op info 5 UWOP_ALLOC_SMALL
02: offs 1, unwind op 0, op info 5 UWOP_PUSH_NONVOL
有没有人设法让它在自己的代码中工作,并能指出我正确的方向?谢谢!
答案 0 :(得分:4)
事实证明,我自己的各种错误导致失败。我已经发现并修复了它们,现在正在解开它们。特别是在某些情况下,代码更改后RtlDeleteFunctionTable
之前未调用RtlAddFunctionTable
。同样重要的是不要触摸函数体中的RSP
:这是完全合理的,但在MSDN文档中并没有真正说明。