我正在用C ++編寫並進行練習以熟悉DLL和共享對象(.so)。如何導出內部文件而不導出它們? GetProcAddress 在未導出函數的調用上返回null。我寫了DLL,所以我知道所有的函數和變量名。
我正在用C ++編寫並進行練習以熟悉DLL和共享對象(.so)。如何導出內部文件而不導出它們? GetProcAddress 在未導出函數的調用上返回null。我寫了DLL,所以我知道所有的函數和變量名。
如果您知道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中調用私有函數的一般機制。
GetProcAddr
Windows API用於檢索已導出函數的地址。對於未導出的函數,它將始終返回 null
,因為它無法在PE文件中找到它。
導出函數是使其可用於其他可執行文件的原因。不導出函數在可執行文件中的位置的數據將不可用(這並非完全正確,因為符號可能仍會顯示該信息,但 GetProcAddr
不會使用這些信息)。
如果您仍然希望找到指向未導出函數的函數指針,則需要遵循導出的引用鏈。例如,如果 func1
使用 func2
並且 func1
已導出,則可以獲取 func1的地址
,然後反彙編 func1
,直到在其中找到對 func2
的調用。識別正確的電話可能有些棘手,但這絕對是可行的。