Мое приложение (написанное в Delphi, но это не имеет особого значения) генерирует куски кода динамически (он содержит встроенный компилятор). Чтобы исключения из Windows x64 работали корректно, мне нужно описать сгенерированные функции через RtlAddFunctionTable
. До сих пор так хорошо, что я изменил генератор кода, чтобы использовать только официальные формы пролога и epilog, и я закодировал их, установив RUNTIME_FUNCTION, содержащий UNWIND_INFO и т.д.
Тем не менее, (преднамеренное) нарушение прав доступа в сгенерированном коде все еще приводит к немедленному завершению приложения, поэтому, очевидно, что-то не так. Используя 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
Кто-нибудь сумел заставить это работать в своем собственном коде и может указать мне в правильном направлении? Спасибо!