☠️
smadi0x86 Playground
  • 💀Welcome to smadi0x86 Playground
    • 🍷Resources
    • 🚬Projects
    • 🎓Certifications
    • 📌Pinned
    • ❓Questions
    • 📞Contact
  • 🏞️Cloud Native
    • Docker
      • Quick Reference
      • Introduction
      • Containers
      • Images
      • Storage & Volumes
      • Security
      • Cheatsheet
    • Git
    • Serverless Framework
    • YAML
  • 🔨Software Engineering
    • System Design
    • Environment Variables
    • JSON Web Tokens
  • 👾Architecture
    • C Language
      • Introduction
      • Calling Conventions
      • GCC Compilation
      • Libraries & Linking
      • I/O
      • Files
      • Pointers
      • Dynamic Memory Allocation
      • Data Types
      • Strings Manipulation
      • Bit Manipulation
      • Pre-processors
      • Macros
      • Type Qualifiers
    • C/C++ Build Systems
      • Fundamentals for Linking
      • Symbolic Linking
      • Cross-Platform Compilation
      • CMake for Building and Linking
      • Shared Libraries
      • Dynamic Linking and Dependency Management
    • Operating Systems
      • OS & Architecture
      • Processes
      • CPU Scheduling
      • Memory Management
  • 🛩️Cyber Warfare
    • Flight Physics
    • Communication
      • PWM & PPM
      • MAVLink
  • 🏴‍☠️Offensive Security
    • Active Directory
      • Introduction
    • Web Attacks
      • Server Side
        • OS Command Injection
        • Information Disclosure
        • Directory Traversal
        • Business Logic
        • Authentication
        • File Upload
        • SSRF
      • Client Side
        • CSRF
        • XSS
    • Recon
      • Active
        • Host discovery
        • Nmap
        • Mass Scan
      • Passive
        • Metadata
      • Web Applications
        • Discovery
        • Subdomains & Directories
        • SSL Certs
        • CMS
        • WAF Detection
      • Firewall Evasion
  • Binary Exploitation
    • Stack Smashing
      • x86
      • x86_64
    • pwntools
      • Processes and Communication
      • Logging and Context
      • Cyclic
      • Packing
      • ELF
      • ROP
  • 😈Advanced Persistent Threat
    • C2
      • Sliver
    • Malware
      • Windows Internals
        • PEB
      • Academy
        • Basics
      • Sektor7
        • Essentials
  • 💌Certifications
    • AWS Certified Cloud Practitioner (CLF-C01)
      • Cloud Foundations
      • Domain 1: Cloud Concepts
      • Domain 2: Security and Compliance
      • Domain 3: Technology
      • Domain 4: Billing and Pricing
    • AWS Certified Solutions Architect - Associate (SAA-C03)
      • Foundation
    • Certified Kubernetes Administrator (CKA)
      • Core Concepts
      • Scheduling
      • Logging & Monitoring
      • Application Lifecycle Management
      • Cluster Maintenance
      • Security
      • Storage
      • Networking
      • Design Kubernetes Cluster
      • Kubernetes The Kubeadm Way
      • Troubleshooting
      • JSONPATH
      • Lightning Lab
      • Mock Exams
      • Killer Shell
    • Certified Kubernetes Security (CKS)
      • Foundation
      • Cluster Setup
      • Cluster Hardening
      • Supply Chain Security
      • Runtime Security
      • System Hardening
      • Killer Shell
    • (KGAC-101) Kong Gateway Foundations
      • Introduction to APIs and API Management
      • Introduction to Kong Gateway
      • Getting Started with Kong Enterprise
      • Getting Started with Kong Konnect
      • Introduction to Kong Plugins
  • 📜Blog Posts
    • Modern Solutions For Preventing Ransomware Attacks
Powered by GitBook
On this page
  • Introduction
  • Interface and Implementation
  • Linking
  • Static vs. Dynamic Linking
  • Library Types
  • Creating Libraries
  • Library Loading
  • Introduction
  • Types of Library Loading
  • Static vs Dynamic Loading
  • Dynamic Loading Mechanics
  • Dynamic Loading API
  • Dynamic Loading Practical Uses
  • Dynamic Loading Code Examples
  • Loading a Dynamic Library
  • Using a Function from a Dynamically Loaded Library
  • Dynamically Loading Optional Features
  • Conclusion
  1. Architecture
  2. C Language

Libraries & Linking

Introduction

  • Libraries are crucial to ensure reusability and modularity of code.

  • They contain one or more object files, which consist of object code.

  • C functions beneficial to multiple applications should be compartmentalized into libraries.

  • Libraries can reference functions in other libraries, e.g., standard C or math libraries.

Interface and Implementation

  • Interface: Defined in a header file (.h).

  • Implementation: Defined in a .c file.

Linking

  • When a C program is compiled, the compiler generates object code (.o or .obj).

  • After generating object code, the compiler invokes the linker.

  • Linking combines multiple object files to create a single executable file.

  • Main goal: Make the library functions available to your program.

    • Can copy the library function code to object code.

    • Alternatively, it can ensure the code is available at runtime.

  • Static Linking: Library functions are copied to the executable file.

  • Dynamic Linking: Only the name of the library is in the binary file; the actual linking occurs when the program runs.

Static vs. Dynamic Linking

Static Linking:

  • Libraries are linked at compile-time.

  • Advantages: No runtime symbol resolution; once bundled, you're certain the correct library version is in use.

  • Disadvantages: Creates larger binaries; no way to update the library without rebuilding the whole program.

Dynamic Linking:

  • Libraries are linked at runtime.

  • Advantages: Saves on disk and memory; all programs linked to a library share a single copy of that library in memory.

  • Disadvantages: Small runtime penalty due to symbol resolution at runtime.

Library Types

Static Libraries (.a or .lib):

Uses static linking; each process has its own copy of code and data.

Dynamic Libraries (.so or .dll):

Linked at runtime; code is shared but data is specific to each process.

Creating Libraries

Static Libraries:

Created using ar (archive) utility. Typical naming convention: lib<name>.a.

Dynamic Libraries:

Created using the link editor (ld). Typical naming convention: lib<name>.so or .dll.

Library Loading

Introduction

When a program uses a library, the library's contents must be made available to the program either at compile-time or runtime.

This process is called "loading". Depending on when and how the library's content is made available, loading can be categorized into different types.

Types of Library Loading

Static Loading (or Load-time Linking):

  • Occurs at compile time.

  • The code from the library is incorporated into the final executable during the linking phase.

  • The resulting binary becomes larger because it contains the code it needs.

  • If the library updates, the program must be re-linked and possibly recompiled to benefit from the changes.

Dynamic Loading (or Run-time Linking):

  • Occurs at runtime.

  • The library's code isn't included in the executable but is accessed as needed while the program runs.

  • Requires that the library is present on the system during execution.

  • The program can benefit from updates to a library without recompilation, just a restart.

Static vs Dynamic Loading

Advantages of Static Loading:

  • No dependencies required at runtime: Since all the code is bundled within the executable, there's no need for external libraries at runtime.

  • Execution speed: Directly contains all the necessary library code, which might make it slightly faster at startup.

Advantages of Dynamic Loading:

  • Smaller executables: Since library code isn't bundled, the executable size is smaller.

  • Shared libraries: Multiple programs can use a single library copy, conserving memory.

  • Updates: Programs can benefit from library updates without recompilation.

Dynamic Loading Mechanics

When a program requires a function from a dynamically loaded library:

  • The loader checks if the library is already loaded into memory.

  • If not, it finds the library on disk (using system paths and environment variables like LD_LIBRARY_PATH).

  • The loader allocates memory and loads the library.

  • The program can then access and execute the library's functions.

Dynamic Loading API

The dynamic loading API allows explicit control over the loading and unloading of shared libraries at runtime.

  • dlopen(): Opens a dynamic library and returns a handle.

    • RTLD_LAZY: Resolves symbols as needed.

    • RTLD_NOW: Resolves all symbols immediately.

  • dlsym(): Retrieves the address of a function or variable from the library using the handle.

  • dlclose(): Closes an opened library.

  • dlerror(): Fetches a human-readable error string for the most recent dynamic loading API error.

Dynamic Loading Practical Uses

  • Plugins: Software can be extended without modifying the core executable.

  • Modular Programs: Only load parts of the software that are needed, conserving resources.

  • Optional Features: If a library isn't present, the software can still run with reduced functionality.

Dynamic Loading Code Examples

Loading a Dynamic Library

#include <stdio.h>
#include <dlfcn.h>

int main() {
    // Load the math library
    void *handle = dlopen("libm.so.6", RTLD_LAZY);
    
    if (!handle) {
        fprintf(stderr, "Error loading library: %s\n", dlerror());
        return 1;
    }

    printf("Library loaded successfully.\n");

    // Close the library
    dlclose(handle);
    return 0;
}

Using a Function from a Dynamically Loaded Library

This example will dynamically load the math library (libm) and utilize the cos function:

#include <stdio.h>
#include <dlfcn.h>

int main() {
    void *handle = dlopen("libm.so.6", RTLD_LAZY);
    if (!handle) {
        fprintf(stderr, "Error loading library: %s\n", dlerror());
        return 1;
    }

    // Get the cosine function
    double (*cosine)(double) = dlsym(handle, "cos");
    if (dlerror() != NULL) {
        fprintf(stderr, "Error loading function: %s\n", dlerror());
        dlclose(handle);
        return 1;
    }

    // Use the cosine function
    double result = cosine(1.0);
    printf("cos(1) = %f\n", result);

    dlclose(handle);
    return 0;
}

Dynamically Loading Optional Features

Suppose we have a feature in our software that relies on a specific library. If the library is present, we use the feature; otherwise, the software runs with reduced functionality.

#include <stdio.h>
#include <dlfcn.h>

int main() {
    void *handle = dlopen("libOptionalFeature.so", RTLD_LAZY);
    if (!handle) {
        printf("Running software without optional feature.\n");
    } else {
        void (*optionalFeature)(void) = dlsym(handle, "runFeature");
        if (dlerror() != NULL) {
            fprintf(stderr, "Error loading function: %s\n", dlerror());
            dlclose(handle);
            return 1;
        }

        // Use the optional feature
        optionalFeature();

        dlclose(handle);
    }

    printf("Software is running.\n");
    return 0;
}

Remember, to compile any of these programs, you would typically use:

gcc program_name.c -ldl -o output_name

The -ldl flag is necessary to link against the dynamic loading functions provided by dlfcn.h.

Conclusion

While static loading offers simplicity and directness, dynamic loading brings versatility and efficiency, especially for large-scale or modular software.

The choice depends on the application requirements, distribution considerations, and the intended user experience.

PreviousGCC CompilationNextI/O
👾