An API granularity based shared library deflation method and system
By employing API-level shared library de-expansion technology, utilizing dependency clustering and mprotect permission switching, combined with a custom dynamic linker and fast path optimization, the problems of insufficient granularity and low memory efficiency in shared library de-expansion are solved, achieving efficient and secure memory management.
Patent Information
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- XIDIAN UNIV
- Filing Date
- 2026-02-12
- Publication Date
- 2026-06-05
Smart Images

Figure CN122152285A_ABST
Abstract
Description
Technical Field
[0001] This invention belongs to the field of computer security technology, specifically relating to a method and system for de-expansion of shared libraries based on API granularity. Background Technology
[0002] In modern operating systems, shared libraries are widely used to reduce disk space and memory usage. However, shared libraries often contain a large amount of code that applications do not actually use (i.e., code bloat), which not only increases memory overhead but, more importantly, expands the attack surface of code reuse attacks (such as return-oriented programming (ROP) and jump-oriented programming (JOP)).
[0003] Existing shared library debloating solutions mainly suffer from the following two core problems: Insufficient granularity in de-inflation identification: Most existing solutions (such as libfilter) belong to "general de-inflation" (Type I), which only removes code that is unreachable under all inputs. This approach is too coarse-grained to handle "context-specific" (Type II) de-inflation, where some code is only needed when a specific API is called and is redundant at other times.
[0004] Side effects of de-bloat removal: Static de-bloat removal, which directly removes code from the binary, breaks the library's generality, causing it to become "private" and unable to be shared between different processes, increasing memory overhead. On the other hand, existing dynamic de-bloat solutions typically remove redundant code at runtime through dynamic overwriting. This write operation triggers the operating system's Copy-on-Write (CoW) mechanism, causing shared physical memory pages to have private copies in each process, resulting in severe memory bloat.
[0005] Dynamic linking and lazy binding are core mechanisms of modern Linux systems. To speed up startup, glibc uses lazy binding by default, meaning that function addresses are resolved and relocated by the dynamic linker (_dl_runtime_resolve) only when the function is first called.
[0006] Code reuse attacks exploit existing code gadgets within a program to execute malicious actions. Debloating techniques, which remove unnecessary code, can effectively reduce the number of usable gadgets in a program, thus mitigating code reuse attacks.
[0007] Existing solutions [Shteinfeld B. Libfilter: Debloating dynamically-linked libraries through binary recompilation[J]. Undergraduate Honors Thesis. Brown University, 2019.] use complex binary-level program analysis techniques to identify dead code in shared libraries that is unreachable under any input; and rewrite all such dead code into trap instructions through binary rewriting. However, they can only remove Type I bloat, which greatly limits their effectiveness. In addition, the shared libraries they generate are application-specific and cannot be shared across applications (i.e., a shared library instance can only serve one specific application), resulting in wasted disk and memory. [Chris Porter, Girish Mururu, Prithayan Barua, and Santosh Pande. 2020. BlankIt library debloating: getting what you want instead of cutting what you don't. In Proceedings of the 41st ACM SIGPLAN Conference on Programming Language Design and Implementation (PLDI 2020). Association for Computing Machinery, New York, NY, USA, 164–180.] BlankIt is a Type II debloator that loads only the library functions needed for specific call points. However, BlankIt requires complex offline pre-training and relies on the heavyweight dynamic binary instrumentation tool Intel Pin, making its deployment difficult. Furthermore, relying on Intel Pin not only incurs performance overhead but also leads to Copy-on-Write (CoW) errors, resulting in memory overhead.
[0008] In summary, the closest solutions to this invention are BlankIt and libfilter. While BlankIt achieves fine-grained control, it has poor practicality; while libfilter has a high degree of engineering sophistication, its granularity is too coarse and it compromises sharing.
[0009] In summary, the existing technology has the following drawbacks: (1) The contradiction between security and ease of use: Type I de-expansioners (such as libfilter) retain all the code that may be used. Although they are easy to deploy, the attack surface left by the attacker is still very large. Type II de-expansioners (such as BlankIt) have fine granularity and greatly limit the gadget resources that attackers can access, but they have high overhead and are complicated to deploy.
[0010] (2) Inefficient memory: The static code removal method leads to multiple versions of library files coexisting and cannot be shared; the dynamic overwrite method triggers CoW, which makes it impossible to share physical memory between processes, violating the design principles of shared libraries.
[0011] (3) Excessive performance overhead: Some dynamic solutions (BlankIt) introduce excessive interception and analysis overhead on each call. Summary of the Invention
[0012] To overcome the problems existing in the prior art, the present invention discloses a method and system for de-expansion of shared libraries based on API granularity; through offline layout reconstruction, functions are rearranged into page-aligned clusters according to API dependencies, laying the foundation for page-level permission control; through runtime permission management (rather than overwriting), the executable permissions of code pages are dynamically adjusted using mprotect, achieving fine-grained de-expansion without triggering CoW, and preserving the memory-sharing attributes of shared libraries; through Fast Path and Hotspot Optimization, the performance loss caused by runtime interception is reduced.
[0013] To achieve the above objectives, the present invention adopts the following technical solution: An API-granular approach to de-bloat shared libraries includes the following steps: Step 1: Offline Analysis and Binary Reconstruction Stage Step 1.1: Perform flow-sensitive pointer analysis on the source code of the shared library, construct a call graph, and calculate the transitive closure of each exported API to obtain the set of all functions that the API depends on, as the dependency set; Step 1.2: Cluster the dependency sets of all APIs, extract the intersection to form disjoint dependency clusters, so that each cluster corresponds to a set of functions that are shared or exclusive among multiple APIs; Step 1.3: Using a binary rewrite tool, rearrange the functions in each dependency cluster in the shared library binary file and force each dependency cluster to be aligned with the operating system memory page size in the file layout; Step 1.4: Generate a metadata mapping table to record the mapping relationship between each exported API and the set of memory pages corresponding to its required dependent clusters; Step 2: Dynamic de-inflation phase during runtime: Step 2.1, deploy a custom dynamic linker. The custom dynamic linker uses a lazy binding mechanism to disable function address relocation, so that every call to the exported API is intercepted and redirected to the dynamic linker; thus meeting the requirement of intervening in every API call. Step 2.2: When the application calls a certain exported API, the dynamic linker queries the metadata mapping table to obtain the set of dependent pages corresponding to the API; Step 2.3: Invoke the operating system's mprotect system call to set the memory pages in the dependent page set to read-executable permissions RX, and at the same time restore the dependent pages that were exclusively occupied by the previous call context to read-only and non-executable permissions RO. Step 2.4, jump to the target API and continue running the program.
[0014] In step 2.3, a reference counter is further associated with each dependent page, and the counter is incremented or decremented at runtime through atomic operations to track and record the number of threads that depend on the page in all currently active threads in real time; the permission of a dependent page is downgraded from RX to RO only when the reference count of a dependent page drops to zero, so as to support secure permission switching in a multi-threaded environment.
[0015] The dynamic de-inflation stage in step two also includes a fast path optimization mechanism: The custom dynamic linker explicitly builds and manages a thread-safe symbol address cache hash table at runtime. After resolving an exported API for the first time, it stores the mapping relationship between the symbol name and the address of the target function in the table. Subsequent calls to the API quickly obtain the address through hash lookup, thereby bypassing the complete symbol resolution process and entering a low-overhead fast execution path. For API calls that have been intercepted and parsed, subsequent calls can directly obtain the target address by looking up the table, skipping the complete symbol lookup process and entering a fast execution path.
[0016] The dynamic de-inflation phase in step two also includes a hotspot API optimization mechanism: Associate a call counter with each exported API, and increment the counter each time a call to that API is intercepted to count the cumulative number of calls. When the number of calls to a certain API exceeds a preset threshold, it is determined to be a hot API; Perform permanent relocation on popular APIs and their dependent clusters, and fix the permissions of their dependent pages to RX. Subsequent calls will no longer go through the interception process and will be executed directly.
[0017] The clustering of dependency clusters adopts a top-down strategy, prioritizing the extraction of common subsets of multiple API dependency sets as independent clusters to ensure no overlap between clusters, thereby supporting precise page-level permission isolation.
[0018] The method is applicable to dynamically linked shared libraries in the Linux operating system environment, the memory page size is 4KB, and the mprotect operation operates at the page granularity in the virtual memory region (VMA).
[0019] The de-expansion method, while preserving the cross-process memory sharing characteristics of shared libraries, reduces the amount of code exposed at runtime to the minimum dependency set required by the current API, reducing the number of available gadgets by an average of more than 90%, and effectively defending against return-oriented programming (ROP) and jump-oriented programming (JOP) code reuse attacks.
[0020] An API-granular shared library de-bloat system includes: The offline refactoring module is used in step one to perform dependency analysis, clustering, function reordering, and metadata generation. A custom dynamic linker module is provided. The custom dynamic linker uses a delayed binding mechanism to disable function address relocation, so that every call to the exported API is intercepted and redirected to the dynamic linker, which meets the requirement of intervening in every API call. It is used in step two and is configured to intercept all exported API calls, query metadata, call mprotect to dynamically adjust the code page execution permissions, and support multi-threaded reference counting, fast path caching and hot API promotion. The refactored shared library, used in steps one and two, has its internal functions organized by API dependency clusters, with each cluster page-aligned in a binary layout.
[0021] The reconstructed shared library is still stored in the standard ELF format. It can be deployed without modifying the application binary, simply by replacing the original shared library file and the corresponding custom dynamic linker, making it transparent to the application.
[0022] A computer-readable storage medium having a computer program stored thereon, which, when executed by a processor, implements the shared library de-expansion method as described above.
[0023] Compared with the prior art, the present invention has the following advantages: I. This invention significantly reduces the attack surface and improves system security by using dependency clustering, page-level mprotect permission switching, and dynamic linker interception.
[0024] Once loaded, all code pages of a traditional shared library are in a readable and executable (RX) state, allowing attackers to construct ROP / JOP attack chains using any gadget within it.
[0025] Step two of this invention uses an API-level de-expansion mechanism to set the memory page containing the smallest set of functions that an API depends on to RX permissions only when the API is called, while the remaining code pages remain read-only and non-executable (RO).
[0026] Real-world testing data shows that this method can achieve a 90% gadget reduction on typical shared libraries (such as libpcre2 and libFLAC); the security boundary is accurate to the API level, effectively blocking cross-API code reuse attack paths and significantly increasing the difficulty of exploiting memory corruption vulnerabilities.
[0027] 2. Avoid copy-on-write (CoW) memory bloat and maintain multi-process sharing efficiency. While conventional "trimming" de-bloat solutions (such as generating multiple simplified .so files) can reduce the code size of a single process, they can lead to different processes loading different versions of libraries, disrupting the sharing of physical memory pages and causing severe CoW memory bloat.
[0028] This invention adopts a unified refactored shared library and runtime permission switching strategy as a whole: With page-aligned layout, all processes still load the same binary file, and physical memory pages are completely shared. mprotect only changes permissions and not content. Permission switching only modifies the permission bits in the page table entry (PTE) and does not trigger page content writing, so it will not cause a Copy-on-Write (CoW). III. Achieving fine-grained, low-overhead runtime dynamic de-expansion Existing static de-expansion tools cannot adapt to scenarios with mixed API calls at runtime. However, step two of this invention is the first to achieve runtime on-demand activation of code regions: each API call exposes only the functions required to pass closures, implementing the principle of least privilege at the API level; PLT calls are intercepted by a customized dynamic linker without modifying the application source code or recompiling; a fast path cache and hot API promotion mechanism (hash cache + hotspot counter) are introduced, making the performance overhead of frequently called APIs approach zero (actual test <2%); although there is a slight delay (about several hundred nanoseconds) for the first call to a less popular API, the overall performance impact is controllable.
[0029] IV. High compatibility, convenient deployment, and transparent to applications. This invention strictly adheres to the ELF standard format. The reconstructed shared library requires no modification to the application; simply replacing the original .so file and the accompanying dynamic linker is sufficient for it to take effect. It supports existing dynamic linking features such as symbol resolution, version control, and weak symbols. It can seamlessly integrate with existing security mechanisms such as ASLR, DEP, and Stack Canary.
[0030] V. Supports multi-threaded safety, ensuring stability in the production environment. To address the issue of multiple threads potentially concurrently calling different APIs in a multi-threaded environment, step two of this invention introduces a page reference counting mechanism: each dependent page maintains an active reference count; it is only downgraded to RO (Restricted Reference Count) when the reference count reaches zero, avoiding accidental permission reduction that could lead to execution errors; ensuring correctness and stability in multi-threaded scenarios such as high-concurrency servers and web frameworks.
[0031] In summary, this invention achieves significant breakthroughs in five dimensions: security, memory efficiency, runtime performance, compatibility, and engineering practicality. In terms of security: the attack surface is compressed to the API level, which greatly reduces the ability to attack by code reuse; In terms of memory: avoid CoW inflation and truly achieve "de-inflation without increasing memory"; In terms of performance: Through caching and hotspot optimization, runtime overhead is reduced to an acceptable range; Deployment: Zero intrusion, zero modification, suitable for the existing Linux ecosystem.
[0032] This invention is particularly suitable for scenarios with extremely high requirements for memory density and security isolation, such as cloud-native, containerized, and microservice architectures, and has significant industrial application value. Attached Figure Description
[0033] Figure 1 This is a flowchart of the overall workflow of the present invention, illustrating the interaction between the offline phase (source code -> dependency analysis -> clustering -> function rearrangement -> new layout library) and the runtime phase (API call -> interception -> permission management -> execution).
[0034] Figure 2 The diagram illustrates the comparison of memory views, showing that at the same time (t1 and t2), different processes (App1, App2) have different access permissions (RX / RO) to different API dependency pages of the same shared library, but the underlying physical pages remain in a shared state.
[0035] Figure 3 The flowchart for runtime optimization of this invention shows the logical branches after an API call, including fast path (cache lookup), slow path (symbol resolution), hotspot detection (counter threshold judgment), and finally de-inflation (mprotect) or API promotion. Detailed Implementation
[0036] The present invention will now be described in further detail with reference to the accompanying drawings.
[0037] Structural Description: The overall architecture of the present invention is as follows Figure 1As shown, it mainly includes two stages: Step 1, Offline Analysis and Binary Reconstruction Phase: Input source code, output reconstructed shared library (with a de-inflating, user-friendly layout) and metadata about dependencies: Step 1.1: Perform flow-sensitive pointer analysis on the source code of the shared library, construct a call graph, and calculate the transitive closure of each exported API to obtain the set of all functions that the API depends on, as the dependency set; Step 1.2: Cluster the dependency sets of all APIs, extract the intersection to form disjoint dependency clusters, so that each cluster corresponds to a set of functions that are shared or exclusive among multiple APIs; Step 1.3: Using a binary rewrite tool, rearrange the functions in each dependency cluster in the shared library binary file and force each dependency cluster to be aligned with the operating system memory page size in the file layout; Step 1.4: Generate a metadata mapping table to record the mapping relationship between each exported API and the set of memory pages corresponding to its required dependent clusters; Step 2, Runtime Dynamic De-expansion Phase: Using a custom dynamic linker, API calls are intercepted during application runtime, and memory permissions of shared libraries are managed based on the currently called APIs and metadata obtained from the offline analysis phase. Step 2.1, deploy a custom dynamic linker. The custom dynamic linker uses a lazy binding mechanism to disable function address relocation, so that every call to the exported API is intercepted and redirected to the dynamic linker; thus meeting the requirement of intervening in every API call. Step 2.2: When the application calls a certain exported API, the dynamic linker queries the metadata mapping table to obtain the set of dependent pages corresponding to the API; Step 2.3: Invoke the operating system's mprotect system call to set the memory pages in the dependent page set to read-executable permissions RX, and at the same time restore the dependent pages that were exclusively occupied by the previous call context to read-only and non-executable permissions RO. Step 2.4, jump to the target API and continue running the program.
[0038] Explanation of the principle: (1) Offline Analysis & Binary Reconstruction: Dependency analysis: Stream-sensitive pointer analysis (based on SVF tools) is used to generate a call graph and calculate the transitive closure of each exported API, which is the set of all functions (dependencies) that the API may call.
[0039] Clustering: To address the issue of overlapping API dependency sets, a top-down clustering algorithm is employed. The intersections of different API dependency sets are extracted as independent clusters, ensuring that all clusters are mutually exclusive.
[0040] Function reordering: This involves using a binary rewriting tool (Egalito) to regenerate the shared library binary based on the clustering results. The key is ensuring that each cluster is page-aligned in memory. This allows runtime precise page-level control of a cluster's permissions via `mprotect` without unintentionally affecting other unrelated functions. A mapping table is also generated to record the set of cluster pages corresponding to each API.
[0041] (2) Runtime API-Level Debloating: Interception Mechanism: Extending glibc's lazy binding mechanism. In a custom dynamic linker, the function relocation step is disabled. This means that each API call will jump back to the dynamic linker (_dl_fixup) instead of directly jumping to the target function, thus achieving interception of each call.
[0042] Access control: When an API is invoked, the linker queries the metadata to determine all the code pages required for that API.
[0043] Use the mprotect system call to make these pages readable and executable (RX).
[0044] At the same time, restore the page that was exclusively occupied by the API in the last call to read-only (RO) (i.e., non-executable).
[0045] Key point: Only page table permissions are modified, not memory content, therefore a Copy-on-Write (CoW) is not triggered, and physical memory pages remain shared across multiple processes. Figure 2In the diagram, two applications, app1 and app2, are using a shared library simultaneously; the dependency metadata of this shared library is shown on the right side of the figure. At time t1, app1 is executing API1, while app2 is executing API2. Therefore, for app1, only the page containing func1 (a dependency of API1) is marked as RX; for app2, only the pages containing func2 and func3 (dependencies of API2) are marked as RX. At time t2, app1 is executing API3, while app2 has finished executing API2 and has not yet executed the next API. Therefore, for app1, only the page containing func4 (a dependency of API3) is marked as RX; for app2, the pages containing the previously executed func2 and func3 (dependencies of API2) are still marked as RX.
[0046] Multi-threading support: Introducing page reference counting (Refcount). This mechanism maintains in real time the number of times each code page is currently depended on by active threads. Only when the reference count of a page drops to zero is its permission restored to read-only (non-executable), thus preventing other threads that depend on the page from crashing due to a single thread revoking permissions.
[0047] (3) Optimization mechanism: Fast Path: Because relocation is disabled, each call requires a symbol lookup. This invention establishes a hash table to cache resolved symbol addresses; subsequent calls directly look up the table, skipping time-consuming symbol traversal. The workflow of the fast path optimization is as follows: Figure 3 As shown. Figure 3 This paper describes the general workflow of the optimization mechanism of this invention. First, when an API is called, the customized dynamic linker checks the cache based on the address of the API symbol name. If the cache is hit, it means that the symbol has been resolved before, and the fast path is entered to directly use the already cached target API address for de-inflation. At this time, the reference count of the API is incremented and checked to see if it exceeds a threshold. If it exceeds the threshold, hotspot optimization is triggered to relocate the API, ensuring that subsequent calls are no longer handled by the customized dynamic linker. Conversely, if the cache is missed, it means that this is the first time the symbol has been resolved, and the slow symbol resolution process must be entered. After the resolution is completed, the result is stored in the cache.
[0048] Hotspot Optimization: A call counter is maintained for each API. When the number of calls exceeds a threshold (e.g., 500,000), it is identified as a hotspot API. At this point, the API and its dependencies are permanently relocated and promoted, and subsequent calls execute directly without going through the interceptor. This achieves a balance between security and performance. The workflow of hotspot optimization is as follows: Figure 3 As shown.
[0049] Performance testing. With the hotspot optimization trigger threshold set to 500,000, this invention resulted in an average performance overhead of 3.7% on SPEC CPU2017 (protecting the glibc shared library), a widely used performance test suite (maximum performance overhead 8%, minimum performance overhead 0.5%). Through caching and hotspot optimization, the runtime overhead was reduced to an acceptable range.
[0050] Security Testing. In simulation experiments, three widely used shared libraries—libpcre2, libz, and libFLAC—were tested (using the test suites provided by these shared libraries as input). Experimental results show that this invention reduces the average number of gadgets by 92.9%, 71.0%, and 93.3%, respectively; it compresses the attack surface to the API level, significantly weakening the ability to exploit code reuse attacks.
Claims
1. A method for de-expansion of shared libraries based on API granularity, characterized in that, include: Step 1: Offline Analysis and Binary Reconstruction Stage Step 1.1: Perform flow-sensitive pointer analysis on the source code of the shared library, construct a call graph, and calculate the transitive closure of each exported API to obtain the set of all functions that the API depends on, as the dependency set; Step 1.2: Cluster the dependency sets of all APIs, extract the intersection to form disjoint dependency clusters, so that each cluster corresponds to a set of functions that are shared or exclusive among multiple APIs; Step 1.3: Using a binary rewrite tool, rearrange the functions in each dependency cluster in the shared library binary file and force each dependency cluster to be aligned with the operating system memory page size in the file layout; Step 1.4: Generate a metadata mapping table to record the mapping relationship between each exported API and the set of memory pages corresponding to its required dependent clusters; Step 2: Dynamic de-inflation phase during runtime: Step 2.1, deploy a custom dynamic linker. The custom dynamic linker uses a delayed binding mechanism to disable function address relocation, so that every call to the exported API is intercepted and redirected to the dynamic linker, thus meeting the requirement of intervening in every API call. Step 2.2: When the application calls a certain exported API, the dynamic linker queries the metadata mapping table to obtain the set of dependent pages corresponding to the API; Step 2.3: Invoke the operating system's mprotect system call to set the memory pages in the dependent page set to read-executable permissions RX, and at the same time restore the dependent pages that were exclusively occupied by the previous call context to read-only and non-executable permissions RO. Step 2.4, jump to the target API and continue running the program.
2. The shared library de-expansion method as described in claim 1, characterized in that, In step 2.3, a reference counter is further associated with each dependent page, and the counter is incremented or decremented at runtime through atomic operations to track and record the number of threads that depend on the page in all currently active threads in real time; the permission of a dependent page is downgraded from RX to RO only when the reference count of a dependent page drops to zero, so as to support secure permission switching in a multi-threaded environment.
3. The shared library de-expansion method as described in claim 1, characterized in that, The dynamic de-inflation stage in step two also includes a fast path optimization mechanism: The custom dynamic linker explicitly builds and manages a thread-safe symbol address cache hash table at runtime. After resolving an exported API for the first time, it stores the mapping relationship between the symbol name and the address of the target function in the table. Subsequent calls to the API quickly obtain the address through hash lookup, thereby bypassing the complete symbol resolution process and entering a low-overhead fast execution path. For API calls that have been intercepted and parsed, subsequent calls can directly obtain the target address by looking up the table, skipping the complete symbol lookup process and entering a fast execution path.
4. The shared library de-expansion method as described in claim 1, characterized in that, The dynamic de-inflation phase in step two also includes a hotspot API optimization mechanism: Associate a call counter with each exported API, and increment the counter each time a call to that API is intercepted to count the cumulative number of calls. When the number of calls to a certain API exceeds a preset threshold, it is determined to be a hot API; Perform permanent relocation on popular APIs and their dependent clusters, and fix the permissions of their dependent pages to RX. Subsequent calls will no longer go through the interception process and will be executed directly.
5. The shared library de-expansion method as described in claim 1, characterized in that, The clustering of dependency clusters adopts a top-down strategy, prioritizing the extraction of common subsets of multiple API dependency sets as independent clusters to ensure no overlap between clusters, thereby supporting page-level permission isolation.
6. The shared library de-expansion method as described in claim 1, characterized in that, The method is applicable to dynamically linked shared libraries in the Linux operating system environment, the memory page size is 4KB, and the mprotect operation operates at the page granularity in the virtual memory region (VMA).
7. The shared library de-expansion method as described in claim 1, characterized in that, The de-inflation method reduces the amount of code exposed at runtime to the minimum dependency set required by the current API while preserving the cross-process memory sharing feature of shared libraries.
8. A shared library de-expansion system for implementing the method as described in any one of claims 1–7, characterized in that, include: The offline refactoring module is used in step one to perform dependency analysis, clustering, function reordering, and metadata generation. A custom dynamic linker module is provided, wherein the custom dynamic linker uses a delayed binding mechanism to disable function address relocation, so that each call to the exported API is intercepted and redirected to the dynamic linker, thus meeting the requirement of intervening in each API call. Used in step two, it is configured to intercept all exported API calls, query metadata, call mprotect to dynamically adjust code page execution permissions, and support multi-threaded reference counting, fast path caching, and hot API promotion. The refactored shared library, used in steps one and two, has its internal functions organized by API dependency clusters, with each cluster page-aligned in a binary layout.
9. The shared library de-expansion system as described in claim 8, characterized in that, The reconstructed shared library is still stored in the standard ELF format. It can be deployed without modifying the application binary, simply by replacing the original shared library file and the corresponding custom dynamic linker, making it transparent to the application.
10. A computer-readable storage medium, characterized in that, It stores a computer program that, when executed by a processor, implements the shared library de-expansion method as described in any one of claims 1–7.