2014-01-08 36 views
10

我的應用程序(用Delphi編寫,但實際上並不重要)動態生成代碼塊(它包含內置編譯器)。爲了讓Windows x64的異常正常工作,我需要通過RtlAddFunctionTable來描述生成的函數。到目前爲止,我已經將代碼生成器更改爲僅使用官方序言和epilog格式,並且通過設置包含UNWIND_INFO的RUNTIME_FUNCTION對它們進行了編碼。在Windows x64上用RtlAddFunctionTable描述動態生成的代碼

但是,(故意的)訪問違規生成的代碼仍然會導致應用程序立即終止,所以顯然有些問題是錯誤的。使用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不打印展開信息?我誤解了補償如何工作?

比較常規的德爾福功能:

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

你看過[this](http://factor-language.blogspot.com/2010/04/frame-based-structured-exception.html)的實現嗎?特別地,指向[HotSpot Java實現](http://hg.openjdk.java.net/jdk7/jsn/hotspot/file/d9bc824aa078/src/os_cpu/windows_x86/vm/os_windows_x86.cpp)的指針也可以是價值 –

+0

是的,但他們只安裝一個異常處理程序,並沒有實現我需要的完全展開。 –

回答

4

事實證明,我自己的各種錯誤導致它失敗。我發現並修復了它們,現在展開工作正常。具體而言,有些情況下RtlDeleteFunctionTable在代碼更改時未在RtlAddFunctionTable之前調用。另外重要的是不要在功能體中觸碰RSP:這是非常有意義的,但在MSDN文檔中沒有詳細說明。

+0

爲了澄清,你也可以使用例如RBP作爲幀指針,這可以在需要時更改RSP。 –