如何在沒有資料的情況下調用Linux連結庫

來源:互聯網
上載者:User

引言

Moto E2是一部具有相當性價比的Linux智能手機,但是由於某些商業上的原因並沒有開放其本地的圖形庫SDK,導致其競爭力與擴充性大幅度的降低。本文以我在編寫其應用中獲得的經驗,介紹如何在沒有相關資料的情況下匯出對應的標頭檔並且編寫相應的程式碼。

注意,本文並非面對一般的手機使用者,如果想順利的閱讀這篇文章,請首先學習一些相關的C/C++知識以及編譯知識。當然,由於本人所學限制,可能有錯誤,甚至是繆誤,也歡迎眾多高手斧正討論。另外,這篇文章所描述的方法並不只限於Moto E2的EZX圖形庫的使用方法,理論上能夠應用於任何類似的環境。

一. 原理

為了破解這些沒有資料的動態串連庫,首先必須理解在linux下面的程式編譯。下面首先假定需要破解的動態串連庫是某個系統的基礎(例如,Moto E2手機的圖形庫即EZX,這是一個基於QT2.3.8的擴充圖形庫,也就是我們需要破解的部分),否則作為非通用性(僅對當前系統而言)沒有任何的實際意義。

Linux的程式在連結庫的使用方式上有三種。

1.編譯時間連結.a庫檔案並將起代碼拷貝到產生的二進位檔案中,運行時脫離.a庫檔案運行。

2.編譯時間連結.so庫檔案並將其作為引用產生二進位檔案,運行時需要依賴相應.so檔案。

3.在程式用以動態連結程式庫的方式調用相關的.so庫檔案,在編譯器不依賴這些.so檔案,但是在運行期需要依賴這些.so檔案。

作為現狀來說,第一種方式首先被排除了,因為作為發行版不可能有.a靜態連結庫。第三種方式也並不適合,因為在編譯器不依賴庫檔案,導致我們不能正確的判斷相應函數的類型,反而造成破解效率的低下,當然還有更重要的原因會在後面提到。因此選擇第二中方式是比較合適的。

那麼,使用第二種方式我們需要那些東西才能正確的編譯一個程式呢?

首先,原始碼是必須的,就是真正我們寫的程式;其次,是so連結庫,這是我們程式啟動並執行基礎;最後,是串連程式和so連結庫的標頭檔。這個標頭檔是用於描述so連結庫的基礎。(當然,一個相應的gcc也必不可少)。

源檔案是我們自己寫的東西,so檔案是從目標系統中匯出的,現在我們缺乏的僅僅是相應的標頭檔。只要我們得到這個標頭檔,即可自由的編譯基於目標系統的程式。

另外補充一點,用這種方式產生的二進位可執行檔和so連結庫的聯絡在調用時依賴的是函數名稱的文本方式,這也是我們破解原理的基礎。

二. 匯出函數列表

由於能夠找到相應的gcc以及匯出so連結庫,大部分人都能夠通過簡單的nm命令匯出so連結庫的函數列表,只需要對相應的so連結庫(例中連結庫名稱為a.so)

arm-linux-nm -gsDC --format=bsd –defined-only a.so

當然在運行這段代碼之前要設定正確的環境變數,本文重在講述原理,這些具體實施細節上就不那麼嚴謹了。當然你也可以使用其他的方式來調用nm指令,只是上面給出的參數能夠獲得至少是我比較滿意的效果。

這樣就可以匯出這個庫檔案的匯出函數庫。例如某so檔案的匯出函數庫為:

...

4184cde8 T colorToString(QColor)

418ab0c4 T setLanguageId(int)

4184cb70 T stringToColor(QString)

....

41a21244 T KbAltItems::initMetaObject()

41a21358 T KbAltItems::staticMetaObject()

41a21424 T KbAltItems::signalChooserResults(int, int, QString const&, int)

41a212b8 T KbAltItems::tr(char const*)

......

在這裡我們可以得到相應的函式宣告,唯一沒有的僅僅是傳回值,幸好作為基礎庫函數一般來說有良好的命名規範,我們大體上能夠從函數名稱上猜出其傳回值。當然這或許需要一定的經驗積累以及良好的運氣作為基礎。

比如

4184cde8 T colorToString(QColor)

4184cb70 T stringToColor(QString)

這兩個函數明顯是一對配對的函數進行顏色和字串的相互轉換,那麼其正確的形態我們能夠很簡單的得出:

QString colorToString(QColor);

QColor stringToColor(QString) ;

這樣在我們的程式中直接聲明這樣的函數,並且在編譯時間指明連結相應的so檔案就能成功的編譯通過並且使用這兩個函數為我們的程式服務。

當然在很多時候這些函數並非那麼輕易的得出傳回值的說明,有時候對於某些函數放棄傳回值,直接聲明void或許是一個比較好的折衷選擇。

如果你的目標是純C的連結庫,恭喜你,現在你已經成功的破解並且能夠使用了,當然我相信既然你點開了這篇文檔,那麼你的目標系統必然不是純C寫的系統。那麼,對於C++的連結庫應該怎麼處理呢?

三. 處理C++的匯出函數

將C++的匯出函數構造成為一個類,並且能夠正常的使用,這是一個漫長的過程,期間拼的不僅僅是良好的技術和豐富的經驗,優秀的運氣和富有親和力的人品才是是否能夠搞定一個系統的關鍵(笑,我就是因為這幾個方面都比較欠缺所以匯出的SDK到現在都是一個半吊子)。

首先,我們需要明確的一點是,so連結庫中,僅僅是函數列表的集合,任何一個類的成員函數,在這裡只是名稱比C函數古怪的普通函數而已。這可能和大家想象的有些大相徑庭,不過正是以為如此我們才使用前面所說的三種方法中的第二種的最根本原因。

因此,一切抱有so中含有類的正確格式資訊的想法都是不現實以及不實際的,因為so連結庫中根本就沒有所謂的C++概念,一切都是編譯器的傑作而已。

還是不提這些問題,我們先把一個類函數表組成一個類的形式:(如上面得到的結果片段)

class KbAltItems

{

public:

void initMetaObject() ;

void staticMetaObject() ;

void signalChooserResults(int, int, QString const&, int) ;

void tr(char const*) ;

};

(由於系統的特殊性,某些函數的特殊處理不再本文的討論之列)

當然既然是匯出函數,必然函數是可見的,屬性都是public。這時候這樣構成一個class已經能夠正確的編寫程式並且通過編譯了,不過很遺憾的是,只要一使用這個類,無論是如何使用,都會立即崩潰,segment fault。

原因事實上很簡單:這個類定義裡面沒有定義正確的成員變數。

無論是直接聲明一個類的對象或者使用new方式,一個對象的大小是在編譯期決定的,其大小是根據標頭檔中類的大小決定的,我們匯出的class中沒有含有相應的成員變數,大小為4(當然為什麼一個什麼都沒有的類的對象也有4個位元組的大小就是另外一段故事了,這裡暫時不討論)。一旦這些成員函數想要調用並沒有分配但是被它“認為”是存在的成員變數時,就會訪問到不恰當的記憶體單元激發系統的記憶體異常,segment fault也是很平常的事情了。

由於so中不存在相應的類格式,那麼正確的使用一個類是不可能的事情了嗎?那也未必。事實上有一種非常粗曠的方法來規避這個問題,當然這個也是這篇文章唯一值得炫耀的一點了:

在類的定義中加入 char tmp[X];作為成員變數。

X的大小我們能夠通過簡單的測試的出來,通過這樣再試試,是不是以前不能啟動並執行類能夠正確運行了?

其原理也非常簡單,既然對象沒有足夠的空間來正確的執行,那麼我們就給它分配一個足夠大的空間讓它正確的執行。

這樣,原始碼、庫、標頭檔我們都有了,那麼,應用程式還會遠嗎?

寫在最後

事實上,成功的構造一個類遠遠不止這些;首先要揣摩類的正確使用方法;其次,類之間的繼承關係我們只有通過類函數的相關性和類名稱的聯絡進行“有限的猜想”。當然,由於使用了上述的那種粗曠的解決方案,只要保證使用了足夠的空間將起所有父類都包括進來,也並非必須;另外,還要對整個系統的架構進行徹底的分析,否則不能將其串連起來;最後,枚舉能夠通過強制轉換int值的方式進行轉換,而純粹的結構體就必須直接放棄了,因為除了名字什麼也沒有,我們只有通過更徹底的閱讀反編譯的代碼進行解讀,破解系統時太消耗時間了。

最後是一個小技巧:對於類中難以使用的類(比如依賴其他的類作為參數的),直接注釋掉就好了,對於連結僅僅連結使用了的函數,沒有使用的函數是不處理的。

預祝對某些系統想入非非的程式員能夠獲得一個讓自己滿意的結果^o^。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.