題:
如何從外部訪問內部DLL函數或數據?
theTheodidact
2018-07-04 01:46:52 UTC
view on stackexchange narkive permalink

我正在用C ++編寫並進行練習以熟悉DLL和共享對象(.so)。如何導出內部文件而不導出它們? GetProcAddress 在未導出函數的調用上返回null。我寫了DLL,所以我知道所有的函數和變量名。

二 答案:
josh
2018-07-04 05:51:27 UTC
view on stackexchange narkive permalink

如果您知道DLL中函數的地址,則可以通過函數指針以“ C”語言進行調用。讓我們舉個例子:

假設您有一個函數駐留在名為“ notExportedFunc”的DLL中,其簽名為

  int notExportedFunc(int a,int b);  

您可以像在下面的主程序中那樣調用它:

  typedef int notExportedFunc(int a,int b); int main(){處理h = LoadLibrary(L“ mydll.dll”); //圖片基址,如果(h == 0){printf(“無法加載mydll.dll \ n”);返回-1; } int funcOffset = 0x11560; //從鏈接器映射int funcAddress =(int)h + funcOffset; notExportedFunc * f =(notExportedFunc *)(funcAddress); int結果= f(3,4); printf(“ Result =%d \ n”,result);}  

在鏈接器映射中,相關條目如下:

0000: 00000000 ___ ImageBase 10000000 < === 鏈接器建議

0001:00000000 __enc $ textbss $ begin 10001000 此處不相關

0001:00010000 __enc $ textbss $ end 10011000 此處不相關

0002:00000560?notExportedFunc @@ YAHHH @ Z 10011560 f dllmain.obj

ImageBase地址由“ LoadLibrary(“ mydll.dll”)”調用返回。您應該意識到,由於ASLR(地址空間佈局隨機化),每次調用LoadLibrary時,該地址通常都會更改。因此,不能直接從鏈接器映射中獲取notExportedFunc的地址,而必須進行計算。在我們的示例中,偏移量為0x11560,必須將其添加到LoadLibrary返回的地址中。

程序的其餘部分通常是通過函數指針進行的“ C”函數調用。

也許可以進一步自動執行此操作,但是該示例有望顯示在DLL中調用私有函數的一般機制。

NirIzr
2018-07-04 14:25:27 UTC
view on stackexchange narkive permalink

GetProcAddr Windows API用於檢索已導出函數的地址。對於未導出的函數,它將始終返回 null ,因為它無法在PE文件中找到它。

導出函數是使其可用於其他可執行文件的原因。不導出函數在可執行文件中的位置的數據將不可用(這並非完全正確,因為符號可能仍會顯示該信息,但 GetProcAddr 不會使用這些信息)。

如果您仍然希望找到指向未導出函數的函數指針,則需要遵循導出的引用鏈。例如,如果 func1 使用 func2 並且 func1 已導出,則可以獲取 func1的地址,然後反彙編 func1 ,直到在其中找到對 func2 的調用。識別正確的電話可能有些棘手,但這絕對是可行的。

在DLL可能更改/更新的情況下,這是一個更好的選擇。我在利用DLL調用內部函數的漏洞中也看到了這一點。儘管這將很難實現OP,但是它幾乎不會中斷(假設函數的調用鍊是相同的)。


該問答將自動從英語翻譯而來。原始內容可在stackexchange上找到,我們感謝它分發的cc by-sa 4.0許可。
Loading...