全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:5784
推到 Plurk!
推到 Facebook!

如何利用BCB載入沒有lib的DLL檔 ?

答題得分者是:arisaka_matsuri
tss1433
一般會員


發表:2
回覆:2
積分:0
註冊:2008-03-21

發送簡訊給我
#1 引用回覆 回覆 發表時間:2008-12-26 21:48:35 IP:122.122.xxx.xxx 訂閱
大家好 

我知道版上有許多關於載入DLL的文章 , 但是我參閱了許多文章依然無法順利載入我的DLL ,

所以才多po了這篇,希望大家能給我一些指導與幫助,先謝過~~

------------------以下是問題的開始--------------------

首先我有一個WindowDisplay.dll的檔案,但是沒有lib檔,也不知道是由哪套程式編譯而成,

於是我先利用了tdump.exe查看export section,得到下列結果

xports from WindowDisplay.dll
19 exported name(s), 19 export addresse(s). Ordinal base is 1.
Sorted by Name:
RVA Ord. Hint Name
-------- ---- ---- ----
00001A20 1 0000 ??0CWindowDisplay@@QAE@XZ
00001000 2 0001 ??4CWindowDisplay@@QAEAAV0@ABV0@@Z
000015E0 3 0002 ?BltDemoText@@YAHH@Z
00001450 4 0003 ?BltPattern@@YAHHKKPAK@Z
00001570 5 0004 ?BltRTText@@YAHHN@Z
000014F0 6 0005 ?BltText@@YAHHHHH@Z
000016A0 7 0006 ?BltTextA@@YAHHHHHH@Z
000014B0 8 0007 ?Clear@@YAXK@Z
000014D0 9 0008 ?DisplayPattern@@YAHXZ
00001820 10 0009 ?DrawBlock@@YAJPAKPAHH@Z
000018C0 11 000A ?DrawSprite@@YAJPAKH@Z
00001960 12 000B ?FreeDD@@YAHHH@Z
000012B0 13 000C ?Get_Scr_Height@@YAKXZ
000012A0 14 000D ?Get_Scr_Width@@YAKXZ
000012C0 15 000E ?InitDD@@YAHPAUHWND__@@K@Z
000013C0 16 000F ?InitialSurface@@YAHHHPAK0@Z
00001070 17 0010 ?UpdateGammaRamp@@YAXPAK00@Z
00001120 18 0011 ?fnWindowDisplay@@YAHPAUHWND__@@@Z
0000D82C 19 0012 ?nWindowDisplay@@3HA

從上面的結果,我猜測是由Visual C 編譯的(不知道我的猜測正確嗎??)

參考 http://delphi.ktop.com.tw/board.php?cid=168&fid=912&tid=83851 的結果得到

利用 implib -a -c -f xxx.lib xxx.dll ::a switch force add _ alias to MS cdecl

來製作一個lib給BCB利用 ~ 於是得到一個WindowDisplay.lib

於是我開啟一個新的bcb project

開一個新個head file,名為 user.h內容如下
int __declspec(dllexport) __stdcall Get_Scr_Height();

主程式內容如下
[code delphi]
#include
#pragma hdrstop

#include "Unit1.h"
#include "user.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
Edit1->Text = IntToStr(Get_Scr_Height) ;
Edit2->Text = Screen->Height ;
}

[/code]

接著將我產生lib檔,Add to project導入 ,但執行的結果得到
[Linker
Error] Unresolved external '__stdcall Get_Scr_Height()' referenced from
C:\DOCUMENTS AND SETTINGS\ADMINISTRATOR\桌面\TEST3\UNIT1.OBJ
不道是哪個環節出了錯誤??

之後參考了 蕭沖兄的blog http://aftcast.pixnet.net/blog/post/22191720
想說自己來改改看def檔,但是def檔結果如下

EXPORTS
??0CWindowDisplay@@QAE@XZ @1 ; ??0CWindowDisplay@@QAE@XZ
??4CWindowDisplay@@QAEAAV0@ABV0@@Z @2 ; ??4CWindowDisplay@@QAEAAV0@ABV0@@Z
?BltDemoText@@YAHH@Z @3 ; ?BltDemoText@@YAHH@Z
?BltPattern@@YAHHKKPAK@Z @4 ; ?BltPattern@@YAHHKKPAK@Z
?BltRTText@@YAHHN@Z @5 ; ?BltRTText@@YAHHN@Z
?BltText@@YAHHHHH@Z @6 ; ?BltText@@YAHHHHH@Z
?BltTextA@@YAHHHHHH@Z @7 ; ?BltTextA@@YAHHHHHH@Z
?Clear@@YAXK@Z @8 ; ?Clear@@YAXK@Z
?DisplayPattern@@YAHXZ @9 ; ?DisplayPattern@@YAHXZ
?DrawBlock@@YAJPAKPAHH@Z @10 ; ?DrawBlock@@YAJPAKPAHH@Z
?DrawSprite@@YAJPAKH@Z @11 ; ?DrawSprite@@YAJPAKH@Z
?FreeDD@@YAHHH@Z @12 ; ?FreeDD@@YAHHH@Z
?Get_Scr_Height@@YAKXZ @13 ; ?Get_Scr_Height@@YAKXZ
?Get_Scr_Width@@YAKXZ @14 ; ?Get_Scr_Width@@YAKXZ
(以下省略)

怎麼會多出個??讓我更懷疑他是不是Visual C 編譯出來的.....實在不知道該怎麼下手 >"<

目前只是想先利用Get_Scr_Height的功能將螢幕的解析度抓出,來測試能不能載入DLL檔~~

希望各位前輩能夠幫我找出問題所在,感激不盡~附上dll檔
編輯記錄
tss1433 重新編輯於 2008-12-29 22:47:05, 註解 無‧
tss1433 重新編輯於 2008-12-29 22:47:28, 註解 無‧
arisaka_matsuri
高階會員


發表:25
回覆:205
積分:231
註冊:2003-10-19

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-12-28 22:12:02 IP:140.113.xxx.xxx 訂閱
你好

參考這篇 kevincg.wordpress.com/2008/06/18/dynamic-linking-libraries/
直接用explicit linking 的方式動態載入吧
這樣就不用管dll是誰編譯出來的了
tss1433
一般會員


發表:2
回覆:2
積分:0
註冊:2008-03-21

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-12-29 23:25:54 IP:122.122.xxx.xxx 訂閱
感謝回覆~~終於可以讀出來了  ^^ !!! 

我的疑惑在於name mangling 的部分不知道如何處理 ~

PFNAddFunction pfnAdd = (PFNAddFunction)GetProcAddress( myPlugin, "?AddFunction@@YAHHH@Z" );

?AddFunction@@YAHHH@Z <----只要能找出這個,並放在對的位置就ok了 !!即便有mangle過也沒關係!!!

太感謝了~~~困惑了我好多天!!

但是不知道有沒有辦法知道 function 的宣告方式 and input,output ~

不然在只有dll的情況下也猜不出
typedef 是要用typedef int or typedef void ?~ 多謝
arisaka_matsuri
高階會員


發表:25
回覆:205
積分:231
註冊:2003-10-19

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-12-30 10:36:47 IP:61.61.xxx.xxx 訂閱
如果真的沒有head file
還是有方法能將參數數量與大小找出來,只是可能意義不明確

第一是分析反組譯碼,可以找些工具來輔助
比較麻煩,也許要經驗

第二是用vc提供的實用工具,undname.exe
可以用 undname "mangling name" 得到 undecorated name
我不確定這個工具對於非vc編譯出來的dll是否有效
但是跟dumpbin.exe搭配起來,真的是很好用

dumpbin -exports WindowDisplay.dll > export.txt
undname export.txt
會出現
Microsoft (R) COFF/PE Dumper Version 8.00.50727.762
Copyright (C) Microsoft Corporation. All rights reserved.


Dump of file d:\WindowDisplay.dll

File Type: DLL

Section contains the following exports for WindowDisplay.dll

00000000 characteristics
45246D54 time date stamp Thu Oct 05 10:26:28 2006
0.00 version
1 ordinal base
19 number of functions
19 number of names

ordinal hint RVA name

1 0 00001A20 public: __thiscall CWindowDisplay::CWindowDisplay(void)
2 1 00001000 public: class CWindowDisplay & __thiscall CWindowDisplay::operator=(class CWindowDisplay const &)
3 2 000015E0 int __cdecl BltDemoText(int)
4 3 00001450 int __cdecl BltPattern(int,unsigned long,unsigned long,unsigned long *)
5 4 00001570 int __cdecl BltRTText(int,double)
6 5 000014F0 int __cdecl BltText(int,int,int,int)
7 6 000016A0 int __cdecl BltTextA(int,int,int,int,int)
8 7 000014B0 void __cdecl Clear(unsigned long)
9 8 000014D0 int __cdecl DisplayPattern(void)
10 9 00001820 long __cdecl DrawBlock(unsigned long *,int *,int)
11 A 000018C0 long __cdecl DrawSprite(unsigned long *,int)
12 B 00001960 int __cdecl FreeDD(int,int)
13 C 000012B0 unsigned long __cdecl Get_Scr_Height(void)
14 D 000012A0 unsigned long __cdecl Get_Scr_Width(void)
15 E 000012C0 int __cdecl InitDD(struct HWND__ *,unsigned long)
16 F 000013C0 int __cdecl InitialSurface(int,int,unsigned long *,unsigned long *)
17 10 00001070 void __cdecl UpdateGammaRamp(unsigned long *,unsigned long *,unsigned long *)
18 11 00001120 int __cdecl fnWindowDisplay(struct HWND__ *)
19 12 0000D82C int nWindowDisplay

Summary

3000 .data
2000 .rdata
1000 .reloc
9000 .text

接下來就自己看著辦囉:)
tss1433
一般會員


發表:2
回覆:2
積分:0
註冊:2008-03-21

發送簡訊給我
#5 引用回覆 回覆 發表時間:2008-12-30 19:57:31 IP:122.123.xxx.xxx 訂閱
大感謝~~~又學到一招了~~~
系統時間:2024-05-03 5:21:40
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!