① Android/Linux so動態庫分析和反編譯
開發環境的搭建涉及友善smart-210開發板作為平台。在進行so動態庫文件頭分析時,需明確其本質為ELF文件,且利用Elf32_Ehdr結構體定義ELF32頭文件。將armeabi-v7a類型的so動態庫文件放置於Linux系統路徑中,然後在Linux終端進入文件目錄,執行"readelf -h xxxx.so"命令,以查看文件頭部信息。
文件頭部信息包括Magic/e_ident[]用於標識ELF目標文件,Class標記文件類型為32位ELF格式,Data指示數據組織格式為小端格式,Version為當前文件頭版本號1。OS/ABI描述操作系統類,ABI Version為ABI版本號0。Type/e_type指明文件類型,這里是共享庫(Shared Library)。Machine/e_machine顯示機器平台類型為ARM類型,Version/e_version為當前目標文件版本號0x01。Entry point address/e_entry表示程序入口地址,Stars of program headers/e_phoff記錄程序頭表文件偏移,Stars of section headers/e_shoff記錄節區頭文件偏移。Flasgs/e_flags為處理器相關標識,Size of this header/e_ehsize表示ELF頭文件大小,Size of program headers/e_phentsize表示程序頭表頭目大小。Number of program headers/e_phnum表示程序頭表條目數量,Size of section headers/shentsize表示節區頭表條目大小,Number of section headers/e_shnum為節區頭表條目數量。節區頭字元表索引/e_shstrndx。
程序頭表通過Elf32_Phdr結構體描述,此表為數組,數組元素存儲程序頭表條目,描述段或其它信息以准備程序運行。文件段包含多個節區,程序頭表僅在可執行文件或共享對象文件中有意義。
反編譯so動態庫方法採用IDA軟體。首先解壓安裝包,安裝時注意避免中文路徑,隨後根據ReadMe文檔獲取密鑰。安裝完成後,打開軟體並點擊「GO」按鈕,拖拽so動態庫文件至工作區,點擊「OK」按鈕等待反編譯完成。反編譯後,工作區顯示包含機器碼的Hex View-1窗口、匯編代碼的IDA View-A窗口以及保存函數名的Function window窗口。通過雙擊函數名定位到對應函數的匯編代碼。使用Ctrl+F搜索特定函數名,雙擊函數名查看匯編代碼,按下F5即可轉換為C代碼。
② 在windows下使用vs2022編譯v8引擎的穩定版本(2023.7.22)
為了在Windows環境下使用VS 2022編譯v8引擎的穩定版本,本指南將分步驟進行詳細說明。首先,確保環境配置完備:安裝python3.10和Git,同時安裝VS 2022並啟用C++的桌面開發和通用Windows平台開發功能。
下一步是下載v8項目源代碼,但請注意,v8官方已停止在官方網站發布博客來更新穩定版本。因此,推薦訪問谷歌的分支詳情頁,例如chromiumdash.appspot.com,選擇一個穩定版本,例如10.4-lkgr,然後創建名為「v8」的文件夾並進入該文件夾。
配置代理,確保其與您使用的代理工具埠匹配。系統全局代理設置也需相應調整,以便v8項目能夠正確下載依賴。保持cmd窗口和代理程序運行狀態,進行後續操作。
接下來,下載開發工具,訪問commondatastorage.googleapis.com,找到並下載名為「depot_tools」的包,解壓後將其路徑添加至PATH環境變數中,確保Python已安裝且其目錄在PATH中位於depot_tools之前。
回到代理設置完成的cmd窗口,設置環境變數以允許谷歌工具下載Windows相關的工具。執行命令`set DEPOT_TOOLS_WIN_TOOLCHAIN=0`,然後運行`fetch v8`命令拉取源代碼。拉取過程可能需幾分鍾,直至完成。
成功拉取源代碼後,進入v8文件夾,並設置環境變數`DEPOT_TOOLS_WIN_TOOLCHAIN=0`,以確保動態庫編譯模式。使用`git checkout 10.4-lkgr`檢出版本。執行`gclient sync -v`完成依賴處理。
在cmd中運行`python3 tools\dev\v8gen.py x64.release -vv -- is_component_build=true v8_static_library=false`配置x64 release動態庫編譯。若遇到錯誤提示,需確保安裝Windows 10 SDK版本10.0.20348.0,包含「Debugging Tools for Windows」功能。
安裝SDK後,再次編譯動態庫,確保成功後使用ninja工具進行編譯。此過程耗時,且CPU佔用率高,建議避免進行其他操作。
編譯完成後,通過輸入`console.log("test"+4*8),5*7;`測試d8.exe程序,結果輸出`test32,返回35`,表明編譯成功。將動態庫復制至指定文件夾作為運行時。
為運行時准備靜態庫,首先刪除v8文件夾中的out.gn文件夾,設置環境變數`DEPOT_TOOLS_WIN_TOOLCHAIN=0`,使用`python3 tools\dev\v8gen.py x64.release -- v8_monolithic=true v8_use_external_startup_data=false use_custom_libcxx=false is_component_build=false treat_warnings_as_errors=false v8_symbol_level=0 is_clang=false`配置靜態庫編譯,然後使用ninja工具編譯。
成功編譯後,找到並復制v8_monolith.lib作為靜態庫。重復此過程以生成不同版本和環境下的靜態庫。
同樣,為ia32版本執行動態和靜態庫編譯,配置方法與x64版本類似,確保路徑和文件名正確。
完成所有編譯步驟後,即可在本地環境中使用v8引擎的穩定版本。記得將編譯文件存儲並共享,方便使用。
整個過程復雜且耗時,需耐心並仔細遵循每一步驟。希望本指南能幫助您成功編譯v8引擎,如有任何疑問或困難,請查閱相關博客或參考文章。
③ CMake構建靜態庫與動態庫以及使用
用例子的方式通俗易懂地解釋CMake構建靜態庫與動態庫的過程。
任務:用實際操作解釋CMake如何構建靜態庫和動態庫。
准備工作:
編譯共享庫:
採用out-of-source 編譯方法,建立build目錄,在build目錄下執行構建命令,生成libhello.so共享庫。
如果需要調整輸出位置,修改主工程文件CMakeLists.txt中的指令,或在lib/CMakeLists.txt中添加SET(LIBRARY_OUTPUT_PATH)指令。
ADD_LIBRARY指令:
無需填寫全路徑,僅輸入庫名,CMake系統會自動生成庫文件名。提供三種類型,包含EXCLUDE_FROM_ALL參數以避免默認構建。
編譯靜態庫:
靜態庫文件名應與動態庫一致,僅後綴不同。使用ADD_LIBRARY指令添加靜態庫時,若在動態庫編譯基礎上執行,靜態庫構建失敗。修改為hello_static,構建libhello_static.a靜態庫。
通過SET_TARGET_PROPERTIES指令設置輸出名稱、版本號和API版本,實現同時生成libhello.so和libhello.a庫。
動態庫版本號:
動態庫應包含版本號,使用SET_TARGET_PROPERTIES指令配置,具體使用方法在lib/CMakeLists.txt中添加相應代碼。
安裝共享庫和頭文件:
將libhello.a、libhello.so和hello.h安裝到系統目錄,如將hello共享庫安裝到/lib目錄,將hello.h安裝到/include/hello目錄,使用INSTALL指令實現。
使用外部共享庫和頭文件:
建立t4目錄及src目錄,編寫main.c源文件和CMakeLists.txt文件,通過INCLUDE_DIRECTORIES指令引入頭文件搜索路徑,使用LINK_DIRECTORIES和TARGET_LINK_LIBRARIES指令鏈接共享庫,完成可執行文件構建。
使用外部靜態庫:
鏈接靜態庫方法與動態庫類似,使用TARGET_LINK_LIBRARIES指令替換動態庫鏈接指令,實現靜態庫鏈接。
環境變數CMAKE_INCLUDE_PATH和CMAKE_LIBRARY_PATH的使用:
通過環境變數調整頭文件和庫文件搜索路徑,確保非標准路徑中的文件能夠被正確識別和鏈接。
總結:通過實際操作和配置,深入理解CMake在構建靜態庫與動態庫過程中的應用,以及如何通過環境變數優化構建過程。
④ 如何在 Windows 下編譯 OpenSSL
如何在Windows下編譯OpenSSL (VS2010使用VC10的cl編譯器)
1、安裝ActivePerl//初始化的時候,需要用到perl解釋器
2、使用VS2010下的Visual Studio 2010 Command Prompt進入控制台模式(這個模式會自動設置各種環境變數)
3、解壓縮openssl的包,進入openssl的目錄
4、perl configure VC-WIN32
盡量在這個目錄下執行該命令,否則找不到Configure文件,或者指定完整的Configure文件路徑。
5、ms\do_ms.bat
在解壓目錄下執行ms\do_ms.bat命令
6、nmake -f ms\ntdll.mak
7、nmake -f ms\nt.mak
編譯後
在openssl解壓目錄下執行,完成編譯後。輸出的文件在out32dll (6), out32 (7)裡面,包括應用程序的可執行文件、lib文件和dll文件
注意:在運行第五步時,cl編譯器會抱怨說.\crypto\des\enc_read.c文件的read是The POSIX name for this item is deprecated(不被推薦的),建議使用_read。呵呵,我可不想將OpenSSL中的所有的read函數修改為_read。再看cl的錯誤代碼error C2220,於是上MSDN上查找:
warning treated as error - no object file generated
/WX tells the compiler to treat all warnings as errors. Since an error occurred, no object or executable file was generated.
是由於設置了/WX選項,將所有的警告都作為錯誤對待,所以。。。
於是打開OpenSSL目錄下的MS目錄下的ntdll.mak文件,將CFLAG的/WX選項去掉,存檔。。。
繼續執行nmake -f ms\ntdll.mak
=================================
一、編譯並安裝OpenSSL
1、按照標准步驟從源代碼編譯安裝OpenSSL
在編譯OpenSSL前,需要正確安裝Perl,因為在編譯OpenSSL時需要使用到該程序。
下載最新版本的Perl然後安裝之。
下載最新版本的OpenSSL
然後將源碼解壓縮到某個目錄(如 C:\openssl-0.9.8j)中。
進入openssl源碼目錄。
cd c:\openssl-1.0.1e
以下為參照該目錄下的文件INSTALL.W32的執行過程:
運行configure:
perl Configure VC-WIN32
創建Makefile文件:
ms\do_ms.bat
編譯動態庫:
nmake -f ms\ntdll.mak
編譯靜態庫:
nmake -f ms\nt.mak
測試動態庫:
nmake -f ms\ntdll.mak test
測試靜態庫:
nmake -f ms\nt.mak test
安裝動態庫:
nmake -f ms\ntdll.mak install
安裝靜態庫:
nmake -f ms\nt.mak install
清除上次動態庫的編譯,以便重新編譯:
nmake -f ms\ntdll.mak clean
清除上次靜態庫的編譯,以便重新編譯:
nmake -f ms\nt.mak clean
2、如果嫌麻煩,不想編譯,可以直接用別人做好的windows OpenSSL 安裝包(我用的是0.9.8j版),
可以下載 OpenSSL for Windows,直接安裝。
P.S. OpenSSL for Windows 的源代碼有一些數據類型和VC6的編譯器不兼容,我發現的不兼容的數據類型如下:
在OpenSSL安裝目錄的下的include/bn.h文件中,將
#define BN_ULLONG unsigned long long
#define BN_ULONG unsigned long long
#define BN_LONG long long
分別修改為:
#define BN_ULLONG ULONGLONG
#define BN_ULONG ULONGLONG
#define BN_LONG LONGLONG
否則,會出現編譯錯誤。
二、使用OpenSSL
在VC中配置使用以上的函數庫:
點擊菜單:Tools -> Options,彈出對話框"Options",在該對話框中選擇"Directories"標簽。
在"Show directories for:"的"Include files"選項中新增目錄"C:\openssl\include";
"Library files"選擇中新增目錄"C:\openssl\lib"。
然後在需要鏈接OpenSSL函數庫的工程中加入如下兩句:
#pragma comment(lib, "ssleay32.lib")
#pragma comment(lib, "libeay32.lib")
其作用是將OpenSSL所需的庫導入工程中。
三、問題
我在鏈接OpenSSL的靜態函數庫時遇到類似以下的問題:
Linking...
msvcrt.lib(MSVCRT.dll) : error LNK2005: _strchr already defined in libcmtd.lib(strchr.obj)
...
這是由於OpenSSL的靜態函數庫使用的是了VC的多線程DLL的Release版本,而我的程序使用了多線程靜態鏈接的Release版本。
調整OpenSSL的靜態函數庫使用的庫函數版本即可,調整過程如下:
編輯文件 ms\nt.mak,將該文件第19行
"CFLAG= /MD /Ox /O2 /Ob2 /W3 /WX /Gs0 /GF /Gy /nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DDSO_WIN32 -D_CRT_SECURE_NO_DEPRECATE -
D_CRT_NONSTDC_NO_DEPRECATE /Fdout32 -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_SEED -DOPENSSL_NO_RC5 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_TLSEXT -DOPENSSL_NO_KRB5 -
DOPENSSL_NO_DYNAMIC_ENGINE"
中的"/MD"修改為"/MT"。然後重新編譯安裝OpenSSL即可。
四、附錄:在VC中對C/C++ 運行時庫不同版本編譯指令說明
《在VC中對C/C++ 運行時庫不同版本編譯指令說明》一文中詳細介紹了連接不同版本庫的編譯指令如下:
C Runtime Library:
/MD MSVCRT.LIB 多線程DLL的Release版本
/MDd MSVCRTD.LIB 多線程DLL的Debug版本
/MT LIBCMT.LIB 多線程靜態鏈接的Release版本
/MTd LIBCMTD.LIB 多線程靜態鏈接的Debug版本
/clr MSVCMRT.LIB 託管代碼和非託管代碼混合
/clr:pure MSVCURT.LIB 純託管代碼
C++ Standard Library:
/MD MSVCPRT.LIB 多線程DLL的Release版本
/MDd MSVCPRTD.LIB 多線程DLL的Debug版本
/MT LIBCPMT.LIB 多線程靜態鏈接的Release版本
/MTd LIBCPMTD.LIB 多線程靜態鏈接的Debug版本
===============================================
一 配置編譯參數
配置編譯參數是進行OpenSSL編譯的第一步,這一步可以確定系統的環境,使用什麼編譯器,默認安裝路徑以及其他一些選項.步驟如下:
1.安裝perl:下載ActivePerl-5.8.8.822-MSWin32-x86-280952.msi,然後點擊msi文件進行安裝!
2..配置編譯參數:下載openssl-1.0.1e.tar.gz,解壓.
vc:首先在C:\Program Files\Microsoft Visual Studio .NET 2010\VC10\bin\目錄下執行vcvars32.bat,然後在解壓後的openssl-1.0.1e目錄,執行命令配置編譯參數:perl Configure VC-WIN32
bc:在解壓後的openssl-0.9.8g目錄下執行:perl Configure BC-32
二 生成批處理文件
在使用configure腳本配置好的編譯參數後,就可以使用批處理命令來生成編譯腳本.生成編譯腳本根據採用編譯器的不同通常使用不同的批處理文件.就目前來說,使用vc編譯的時候有三種選擇:do_ms,do_masm和do_nasm來創建一系列編譯腳本文件,即.mak腳本.步驟如下:
vc:在openssl-1.0.1e目錄下,執行命令來批處理文件:do_ms,do_masm和do_nasm
bc:1.下載nsm09839.zip微軟匯編編譯器,解壓,拷貝到c:/windows目錄下,修改名稱為nasmw.exe;2.在openssl-1.0.1e目錄下,執行命令來批處理文件:ms\do_nasm
三 代碼編譯
vc:
完成上面步驟後,可以看到兩個關鍵腳本文件:nt.mak和ntdll.mak.如果我們需要編譯後的OpenSSL庫是支持動態DLL形式的,那麼應該使用ntddll.mak文件進行編譯,這樣編譯完成我們會得到四個與OpenSSL的API庫有關文件:ssleay32.lib,libeay32.lib,ssleay32.dll和libeay32.dll.執行的編譯命令形式如下:nmake -f ms\ntdll.mak
如果不希望以動態庫的形式使用OpenSSL,那麼可以使用nt.mak文件進行編譯.這樣編譯後使用OpenSSL的時候,回直接將代碼鏈接進我們的程序裡面.執行命令如下:nmake -f ms\nt.mak
bc:執行命令來完成代碼編譯:make -f ms\bcb.mak
四 ELSE
1)
測試動態庫:
nmake -f ms\ntdll.mak test
測試靜態庫:
nmake -f ms\nt.mak test
安裝動態庫:
nmake -f ms\ntdll.mak install
安裝靜態庫:
nmake -f ms\nt.mak install
清除上次動態庫的編譯,以便重新編譯:
nmake -f ms\ntdll.mak clean
清除上次靜態庫的編譯,以便重新編譯:
nmake -f ms\nt.mak clean
2)
使用OpenSSL
在VC中配置使用以上的函數庫:
點擊菜單:Tools -> Options,彈出對話框"Options",在該對話框中選擇"Directories"標簽。
在"Show directories for:"的"Include files"選項中新增目錄"C:\openssl\include";"Library files"選擇中新增目錄"C:\openssl\lib"。
然後在需要鏈接OpenSSL函數庫的工程中編譯時加入"libeay32.lib"就可以了。
⑤ C++動態鏈接庫的創建與調用(Windows 10 + VSCode + CMake)
本文主要涵蓋如下內容:
在Windows 10環境下,使用VSCode和CMake創建與調用C++動態鏈接庫的具體步驟與技巧。包括准備工作(安裝MinGW-w64和配置VSCode)、使用CHOCOLATEY安裝make工具、配置CMake用於編譯動態鏈接庫等關鍵步驟。文章詳細介紹了從環境搭建、代碼編輯到動態鏈接庫的創建與安裝的全過程,旨在幫助開發者輕松實現C++動態鏈接庫的製作與應用。對於需要離線版PDF文檔以及工程文件的讀者,可通過聯系作者獲取。
准備工作安裝MinGW-w64
MinGW-w64 是將經典C語言編譯器GCC移植到Windows平台的版本,兼容Win32API,支持在Windows環境中編譯Linux平台下的源代碼為可執行程序。它是GCC在Windows環境的實現版本。
下載離線安裝包並直接解壓到指定目錄,添加到系統環境變數,然後通過PowerShell驗證安裝。
代碼編輯器-VSCode配置
從VSCode官網下載安裝,安裝過程中忽略直接進入配置插件步驟。安裝C/C++插件、Code Runner、C++ Intellisense和CMake Tools插件。為方便中文用戶,可選擇安裝VSCode 簡體中文包。
簡易使用教程
使用VSCode打開項目文件夾,創建文件`helloworld.cpp`並填寫示例代碼。通過終端配置默認生成任務,選擇g++編譯器,生成`tasks.json`文件。運行構建任務以編譯代碼。
Windows包管理工具-CHOCOLATEY
CHOCOLATEY 是Windows下的包管理器,安裝後可方便使用make工具。安裝說明、安裝命令、執行策略設置和驗證安裝結果。
使用CHOCOLATEY 安裝make工具
在安裝過程中注意路徑,避免中文路徑引起的安裝錯誤。確保項目文件夾路徑英文命名。
編譯工具-CMake
訪問CMake官網下載並安裝適用於Windows環境的版本。確保在CMake命令中指定編譯器為MinGW。設置環境變數CMAKE_GENERATOR以將MinGW作為默認編譯器。
編寫動態鏈接庫
創建工程結構包括`hello.h`, `hello.cpp`和`CMakeLists.txt`。使用CMakeLists.txt文件配置動態鏈接庫的生成路徑、安裝路徑及與.h文件的安裝路徑。通過命令行執行`make`和`make install`。
動態鏈接庫的查找順序
當exe文件執行時,按照特定順序查找dll文件,因此確保動態鏈接庫的路徑正確。
編寫常式-使用動態鏈接庫
創建新的工程文件夾,編寫源碼文件`hello_demo.cpp`和CMake配置文件`CMakeLists.txt`,定義工程結構並輸出日誌。
編譯原理基礎
靜態鏈接庫在鏈接階段與引用到的庫一起打包到可執行文件中,而動態鏈接庫在程序運行時才被載入內存,避免了空間浪費和更新部署的麻煩。動態庫的創建和使用遵循特定的格式與規則。
參考教程
更多詳細信息和示例可參閱吳秦老師關於C++靜態庫與動態庫的教程,進一步學習與實踐。
⑥ 如何編譯C/Fortran動態/靜態鏈接庫
首先,傳統的編譯,也就是
靜態編譯
是把
源文件
翻譯成目標文件,這個是一次性過程,也就是你所謂的靜態編譯。
後來的Java和.NET等語言,首先編譯成中間形式,然後運行過程中根據需要編譯成本地代碼(注意這個過程不是一次性的,下次運行重新編譯),這個就是JIT(即時編譯)技術,從即時編譯發展出了動態編譯技術
————————————
(傳統的)編譯完成後,像C/C++、Fortran、匯編等語言,可以把多個目標文件合並到一個
庫文件
中,這個就是靜態庫。比如常說的
庫函數
printf就是libc裡面的函數。
如果有了啟動函數(main),main裡面使用了printf,就可以通過
靜態鏈接
技術,從libc中提取出printf所在的文件加入到可執行文件中,如果printf還需要其它函數,就繼續搜索並加入列表,直到形成一個
閉包
。這個就是靜態鏈接。
可是靜態鏈接有個明顯的缺點,如果每個程序都需要printf,那麼printf這個函數的代碼就會同時存在在每個程序中,這樣也太佔地方了吧。所以發明了動態連接技術,其實有兩種形式。無論哪一種,都是首先記錄下需要調用printf這個函數以及所在的
動態庫
,等到運行的時候再載入動態庫,從動態庫中找到真正的printf去執行。
由於,
動態鏈接
技術需要一些額外的信息,傳統的靜態庫是不具備的,這些額外信息主要是重復載入和卸載時所需要的一些代碼,因此需要
動態鏈接庫
。