2017-09-03 299 views
-3

是否有可能使MS Visual C++編譯器將Win32 API導入調用視爲(未解析)外部符號?使MS Visual C++編譯器將Win32 API導入調用視爲(未解析)外部符號

換句話說,我需要改變dword ptr調用,參考了一些IAT,如:

FF 15 00 00 00 00 call  dword ptr [[email protected]] 

到外部符號調用,如:

E8 00 00 00 00  call  [email protected] 

這意味着編譯後我不需要鏈接,因爲顯然這是不可能的。所以作爲一個產品,我想獲得(MS)COFF .obj文件,這種不尋常的Win32 API調用。

+1

爲什麼連接「明顯」不可能? –

+2

這沒有什麼意義,'__imp_MessageBoxA @ 16'與'_MessageBoxA @ 16'完全一樣「無法解析」。這個區別是由聲明中'__declspec(dllimport)'屬性引起的,編譯器#從WinUser.h包含它,這是一個優化。通過重新聲明函數來優化優化並不會使其「更好」,因此始終需要鏈接導入庫。只有使用LoadLibrary + GetProcAddress才能避免鏈接。 –

+0

@BoPersson,因爲Win32 API函數在系統DLL中定義,系統DLL在啓動時加載到進程中。因此,在鏈接階段,您無法使用真正的Win32 API函數來解析這些符號。但是,是的,我必須承認,鏈接可以用「假」符號來完成。 – RIscRIpt

回答

0

正如在問題的評論中指出的,Win32 API調用編譯爲call [__imp__xxx]的原因是__declspec(dllimport)

因此,要實現問題中提出的問題,必須定義所有Win32 API函數,而不必使用__declspec(dllimport)

在Win32頭文件(如WinUser.h)中,您可以看到所有函數都使用宏定義,WINxxxAPI宏又定義在apisetcconv.h中。在後面的文件WINxxxAPI宏定義爲DECLSPEC_IMPORT,而後者又定義爲__declspec(dllimport)

所以,一個簡單的方法來達到要求與以下空預處理器定義(see /D flag),以重新定義DECLSPEC_IMPORT

/DDECLSPEC_IMPORT= 

即相當於

#define DECLSPEC_IMPORT 

附:如果有其他方法,我仍然想知道它們。

+0

只需添加'user32.lib'作爲鏈接器輸入。你有* pe * – RbMm

+0

你會意識到這並不能消除對IAT的需求。對於代碼來說,對'_MessageBoxA @ 16'的調用需要解析爲一個只包含'jmp dword ptr [__imp__MessageBoxA @ 16]'的存根。 –

+0

是的,我明白這一點。您可以查看我的[與RbMm的對話](http://chat.stackoverflow.com/rooms/153552/discussion-between-riscript-and-rbmm)以瞭解背景故事,爲什麼我需要它以及我想要如何使用這個。 Tl; dr:如果您進行運行時鏈接,則不需要IAT,因爲您可以使用GetProcAddr獲取活動進程中所有函數的地址,也可以手動檢查活動進程中的DLL的IAT。 – RIscRIpt