Method for obtaining program address under musl gcc compilation running environment
By obtaining the offset and real address of the dlsym function under the musl-gcc platform and combining it with preloading technology, the problem that ld_preload technology cannot replace JNI_CreateJavaVM() is solved, realizing the embedding and tracking operation and maintenance capabilities of intelligent operation and maintenance tools without modifying service code or recompiling programs.
Patent Information
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- QIMING INFORMATION TECH
- Filing Date
- 2023-11-24
- Publication Date
- 2026-07-24
AI Technical Summary
On the musl-gcc platform, the ld_preload technology cannot replace the JNI_CreateJavaVM() function, making it impossible to achieve intelligent embedding and traceable maintenance without modifying the service code or recompiling the program.
By obtaining the offset and actual address of the dlsym function and combining it with preloading technology, the program address can be obtained on the musl-gcc platform, enabling the injection and modification of JVM startup and Java service parameters.
Without modifying the service code or recompiling the program, the intelligent operation and maintenance tool on the musl-gcc platform has achieved intelligent embedding and tracking of services, and has realized the flexible use of preloading technology by leveraging the dynamic library loading and function address redirection features.
Smart Images

Figure CN117785208B_ABST
Abstract
Description
Technical Field
[0001] This invention relates to the field of the musl-gcc platform, and more particularly to a method for obtaining program addresses in the muslgcc compilation and runtime environment. Background Technology
[0002] Intelligent operation and maintenance tools enable intelligent embedding and tracking of services within a Linux runtime environment without modifying service code or recompiling programs. A common method for dynamic library symbol replacement is using the ld_preload technique; however, ld_preload fails when a service uses dlopen to open a specific library.
[0003] `ld_preload` and `dlopen` are two different methods for loading dynamic link libraries. Their implementation mechanisms differ, so they cannot be used interchangeably. Specifically, `ld_preload` specifies the dynamic link library to be preloaded via environment variables at program startup, while `dlopen` loads the dynamic link library at runtime through function calls.
[0004] Therefore, modifying the `JNI_CreateJavaVM()` function in `jre.so` in Java, simply reloading `JNI_CreateJavaVM()` using the `pre_load` technique, will not achieve the desired replacement. For the glibc platform, the call address of `dlsym` can be obtained through its parent function `_dlsym`. However, for the musl-gcc platform, since musl-gcc is a lightweight standard C library implementation primarily used in embedded Linux systems, it is more lightweight, faster, and more secure than glibc, thus this method is not feasible. Summary of the Invention
[0005] The purpose of this invention is to address the issue that musl-gcc, a simplified version of the glibc library implementation, lacks a parent function for dlsym, which limits the use of preload techniques. This invention proposes a method for obtaining program addresses in the muslgcc compilation and runtime environment. Instead of obtaining the address of the dlopen function in glibc through its parent function __dlopen, the method obtains the address of the core function through the offset of the dynamic library function.
[0006] The steps to obtain the program address in the muslgcc compilation and runtime environment are as follows:
[0007] S1: Get the offset of the dlsym function;
[0008] S2: Obtain the real address of dlsym within the target's service process.
[0009] Furthermore, the method for obtaining the program address in the muslgcc compilation and runtime environment, step S1 includes the following specific steps:
[0010] S11: Start the test program and get the process $Pid of the current process using getpid();
[0011] S12: Open the memory-mapped file / proc / $Pid / maps and search for the memory address / lib / ld-musl-x86_64.so.1;
[0012] S13: Load the searched memory address / lib / ld-musl-x86_64.so.1 into the memory address range;
[0013] S14: Obtain the base address 0xbegin of the dynamic library, and based on the function address 0xdlsym of dlsym, obtain the function offset 0xdlsym-0xbegin of dlsym;
[0014] S15: Record the offset of the dlsym function: 0xdlsym-0xbegin.
[0015] Furthermore, in the method for obtaining the program address in the muslgcc compilation and runtime environment, step S2 includes the following sub-steps:
[0016] S21: In the service process, get the process $Pid of the current process using getpid();
[0017] S22: Open the memory-mapped file / proc / $Pid / maps and search for the memory address / lib / ld-musl-x86_64.so.1;
[0018] S23: Load the searched memory address / lib / ld-musl-x86_64.so.1 into the memory address range;
[0019] S24: Obtain the base address 0xbegin of the dynamic library, and based on the offset of the dlsym function 0xdlsym-0xbegin, obtain the actual address of the dlsym function 0xbegin+0xoffset;
[0020] S25: Use a function pointer to point the function pointer to the actual address of the dlsym function, 0xbegin + 0xoffset, to obtain the actual operation of the dlsym function.
[0021] Furthermore, the method for obtaining program addresses in the muslgcc compilation and runtime environment also includes an intelligent operation and maintenance step:
[0022] I1: Without modifying the service code or recompiling the program, use the Preload technique to inject and modify JVM startup and Java service parameters;
[0023] I2: By preloading specific dynamic link libraries, it enables the interception and injection of JVM startup and Java service parameters during service startup, thereby extending and customizing intelligent operation and maintenance steps.
[0024] The beneficial effects of this invention are as follows: By obtaining the program address in the musl-gcc compilation and runtime environment, the intelligent operation and maintenance tool can intelligently embed and track the operation and maintenance of services in the Linux runtime environment. It makes full use of the characteristics of dynamic library loading and function address redirection, so that the preloading technology can also be flexibly used under the musl-gcc platform. Attached Figure Description
[0025] Figure 1 This is a diagram illustrating the injection of startup parameters during the JVM startup process.
[0026] Figure 2 This is a diagram of the ELF file format. Detailed Implementation
[0027] To provide a clearer understanding of the technical features, objectives, and effects of the present invention, specific embodiments of the present invention will now be described with reference to the accompanying drawings.
[0028] As attached Figure 1 As shown, the glibc platform can obtain the call address of dlsym through the parent function _dlsym of dlsym. However, since the musl-gcc platform modifies the JNI_CreateJavaVM() function in jre.so in java, simply re-running JNI_CreateJavaVM() using the pre_load technique will not achieve the purpose of replacement.
[0029] In C, dynamic libraries are typically formatted as Executable and Linkable Format (ELF), which is also the default format for executable files in Linux systems. ELF files contain executable code, data segments, symbol tables, and relocation tables, allowing the operating system to correctly load and execute the program. A key feature of dynamic libraries is that they can be shared by multiple programs, thus saving memory. However, once a dynamic library is compiled, the relative positions of its functions within the code segment are fixed. Utilizing this characteristic, the relative address of `dlsym` is also fixed.
[0030] As attached Figure 2 As shown, in Linux systems, the address where a dynamic library is loaded can change after a process starts; this is called address redirection. In Linux, when a program is executed, it is loaded into memory, and a segment of address space is allocated in memory to store code and data. Dynamic libraries are the same; they also need to be loaded into memory. During the loading process, if it is found that certain addresses of the dynamic library need to be redirected, redirection processing will be performed. Therefore, in the target service, based on the base address and offset address of the library where dlsym resides, the real address of dlsym can be obtained, as follows:
[0031] The steps to obtain the program address in the muslgcc compilation and runtime environment are as follows:
[0032] S1: Get the offset of the dlsym function;
[0033] S2: Obtain the real address of dlsym within the target's service process.
[0034] Furthermore, the method for obtaining the program address in the muslgcc compilation and runtime environment, step S1 includes the following specific steps:
[0035] S11: Start the test program and get the process $Pid of the current process using getpid();
[0036] S12: Open the memory-mapped file / proc / $Pid / maps and search for the memory address / lib / ld-musl-x86_64.so.1;
[0037] S13: Load the searched memory address / lib / ld-musl-x86_64.so.1 into the memory address range;
[0038] S14: Obtain the base address 0xbegin of the dynamic library, and based on the function address 0xdlsym of dlsym, obtain the function offset 0xdlsym-0xbegin of dlsym;
[0039] S15: Record the offset of the dlsym function: 0xdlsym-0xbegin.
[0040] Furthermore, in the method for obtaining the program address in the muslgcc compilation and runtime environment, step S2 includes the following sub-steps:
[0041] S21: In the service process, get the process $Pid of the current process using getpid();
[0042] S22: Open the memory-mapped file / proc / $Pid / maps and search for the memory address / lib / ld-musl-x86_64.so.1;
[0043] S23: Load the searched memory address / lib / ld-musl-x86_64.so.1 into the memory address range;
[0044] S24: Obtain the base address 0xbegin of the dynamic library, and based on the offset of the dlsym function 0xdlsym-0xbegin, obtain the actual address of the dlsym function 0xbegin+0xoffset;
[0045] S25: Use a function pointer to point the function pointer to the actual address of the dlsym function, 0xbegin + 0xoffset, to obtain the actual operation of the dlsym function.
[0046] Furthermore, the method for obtaining program addresses in the muslgcc compilation and runtime environment also includes an intelligent operation and maintenance step:
[0047] I1: Without modifying the service code or recompiling the program, use the Preload technique to inject and modify JVM startup and Java service parameters;
[0048] I2: By preloading specific dynamic link libraries, it enables the interception and injection of JVM startup and Java service parameters during service startup, thereby extending and customizing intelligent operation and maintenance steps.
[0049] The core code for obtaining the address of the dlsym function is as follows:
[0050] Function to calculate the real address of a function in a sharedlibrary
[0051] void* calculateRealAddress(const char* libraryName, const char*functionName, uintptr_t relativeAddress) {
[0052] void* handle = dlopen(libraryName, RTLD_LAZY | RTLD_LOCAL);
[0053] if (handle == NULL) {
[0054] fprintf(stderr, "Error loading library: %s\n", dlerror());
[0055] return NULL;
[0056] }
[0057] void* functionAddress = dlsym(handle, functionName);
[0058] if (functionAddress == NULL) {
[0059] fprintf(stderr, "Error finding function: %s\n", dlerror());
[0060] dlclose(handle);
[0061] return NULL;
[0062] }
[0063] uintptr_t libraryBaseAddress = (uintptr_t)handle;
[0064] uintptr_t realAddress = libraryBaseAddress + relativeAddress;
[0065] dlclose(handle);
[0066] return (void*)realAddress;
[0067] }
[0068] int main() {
[0069] / / Define the library and function names
[0070] const char* libraryName = " / path / to / ld-musl-x86_64.so.1"; / / Replacewith the actual path
[0071] const char* functionName = "dlsym";
[0072] / / Get the relative address of the function
[0073] uintptr_t relativeAddress = 0x12345678; / / Replace with the actual relative address
[0074] / / Calculate the real address of the function
[0075] void* realAddress = calculateRealAddress(libraryName, functionName, relativeAddress);
[0076] if (realAddress != NULL) {
[0077] printf("Real address of %s: %p\n", functionName, realAddress);
[0078] }
[0079] return 0;
[0080] }
[0081] This approach easily retrieves the address of the dlsym function on both glibc and musl-gcc platforms. Furthermore, the method can be extended to retrieve the actual addresses of functions in other library files. Combined with preloading techniques, it can be used in a wider range of scenarios.
[0082] This solution obtains the program address in the musl-gcc compilation and runtime environment, uses preload technology, and targets JVM startup and Java service parameter injection methods. It enables intelligent operation and maintenance tools to intelligently embed and track services in the Linux runtime environment, making full use of the characteristics of dynamic library loading and function address redirection, so that the preload technology can also be flexibly used under the musl-gcc platform.
[0083] The foregoing has shown and described the basic principles, main features, and advantages of the present invention. Those skilled in the art should understand that the present invention is not limited to the above embodiments. The embodiments and descriptions in the specification are merely illustrative of the principles of the invention. Various changes and modifications can be made to the invention without departing from its spirit and scope, and all such changes and modifications fall within the scope of the present invention as claimed. The scope of protection of this invention is defined by the appended claims and their equivalents.
Claims
1. A method for obtaining program addresses in the muslgcc compilation and runtime environment, characterized in that, The steps are as follows: S1: Obtain the offset of the dlsym function; step S1 includes the following specific steps: S11: Start the test program and get the process $Pid of the current process using getpid(); S12: Open the memory-mapped file / proc / $Pid / maps and search for the memory address / lib / ld-musl-x86_64.so.1; S13: Load the searched memory address / lib / ld-musl-x86_64.so.1 into the memory address range; S14: Obtain the base address 0xbegin of the dynamic library, and based on the function address 0xdlsym of dlsym, obtain the function offset 0xdlsym-0xbegin of dlsym; S15: Record the offset of the dlsym function: 0xdlsym-0xbegin; S2: Obtain the real address of dlsym within the target's service process; step S2 includes the following sub-steps: S21: In the service process, get the process $Pid of the current process using getpid(); S22: Open the memory-mapped file / proc / $Pid / maps and search for the memory address / lib / ld-musl-x86_64.so.1; S23: Load the searched memory address / lib / ld-musl-x86_64.so.1 into the memory address range; S24: Obtain the base address 0xbegin of the dynamic library, and based on the offset of the dlsym function 0xdlsym-0xbegin, obtain the actual address of the dlsym function 0xbegin+0xoffset; S25: Use a function pointer to point the function pointer to the actual address of the dlsym function, 0xbegin + 0xoffset, to obtain the actual operation of the dlsym function.
2. The method for obtaining program addresses in the muslgcc compilation and execution environment according to claim 1, characterized in that, It also includes an intelligent operation and maintenance step: I1: Without modifying the service code or recompiling the program, use the Preload technique to inject and modify JVM startup and Java service parameters; I2: By preloading specific dynamic link libraries, it enables the interception and injection of JVM startup and Java service parameters during service startup, thereby extending and customizing intelligent operation and maintenance steps.