C++中使用_asm彙編呼叫動態庫函式的一點問題
阿新 • • 發佈:2019-01-22
因為從事dll 編寫的相關工作。沒寫完一個dll 之後都要對函式進行測試,對每個dll都要寫一個測試demo的話就非常費勁。能不能一個公共的測試軟體來各種dll裡的函式測試呢?
嘗試開始,從外界的.h檔案中讀取函式名很簡單,但是我們不能在程式已經編譯的過程中再進行新增定義該 函式的指標。
比如我dll中有一個
int add(int a,int b);
從.h中也讀到了add,然而 沒法再在執行中對其進行如下的定義了,必須開始就定義好。typedef int (CALLBACK* Fun_add)(int a,int b);
於是,我們只能從另一種路線入手,通過記憶體地址去查詢這個函式,然後利用匯編向 壓棧引數,然後得到結果。
例如 我們建立一個ADDdll.dll的動態庫,其中有以下函式。
int __stdcall addabc(int a ,int b,int c)
{
int sum = a + b + c;
return sum;
}
在呼叫該函式的exe 中,我們進行如下操作。
請注意程式碼註釋中的★★★處,當我跟蹤彙編的呼叫動態庫的函式過程中,pull出棧時,指標要加上三個引數之前所佔用的空間。然而這個操作,C++編譯器自己已經進行了操作,開始加那句add時錯的一塌糊塗。。。希望這個小建議能幫大家不繞遠路。HINSTANCE hInstLibrary = LoadLibrary(_T("ADDdll.dll")); if( hInstLibrary == NULL) { MessageBox(NULL,_T("動態庫載入失敗"),NULL,MB_OK); } else { MessageBox(NULL,_T("動態庫載入成功"),NULL,MB_OK); int a = 2,b = 3,c = 4; int addstr =(int) GetProcAddress(hInstLibrary,"addabc");//獲得函式的地址 if(addstr == 0) { MessageBox(NULL,_T("函式載入失敗"),NULL,MB_OK); goto RE; } else { //為了檢視函式地址具體值得無聊操作,請無視編碼轉化這種坑 char bb[50] = {0}; sprintf_s(bb,"%x",addstr); WCHAR wszClassName[256]; memset(wszClassName,0,sizeof(wszClassName)); MultiByteToWideChar(CP_ACP,0,bb,strlen(bb)+1,wszClassName, sizeof(wszClassName)/sizeof(wszClassName[0])); MessageBox(NULL,wszClassName,NULL,MB_OK); //--------------------------------------------------------- int result = 0 ;//用來取結果 _asm { push c push b push a //對三個引數壓棧 call addstr//召喚這個等食的函式 mov dword ptr [result],eax //取回結果,一般函式結果都在eax中。 } //★★★add esp,12 前期push的3個int 是12個位元組,C++ 編譯器自己進行了ret 8 真是吊 //對取得的結果進行格式化輸出。 memset(bb,0,sizeof(bb)); sprintf_s(bb,"%d",result); memset(wszClassName,0,sizeof(wszClassName)); MultiByteToWideChar(CP_ACP,0,bb,strlen(bb)+1,wszClassName, sizeof(wszClassName)/sizeof(wszClassName[0])); MessageBox(NULL,wszClassName,NULL,MB_OK); } } return TRUE; RE: return FALSE;
至於測試工具,就是文書處理歸類的工作了,是上邊那段程式碼的擴充套件了。