diff options
| author | Pali Rohár <pali.rohar@gmail.com> | 2023-12-29 23:19:48 +0100 |
|---|---|---|
| committer | Silvio <silvio.traversaro@iit.it> | 2025-04-28 14:49:51 +0200 |
| commit | c815879efea297cad9d9fbf76baf972d49dd97fa (patch) | |
| tree | 94f3e466898353600e4b9c037cdb8b1c65fb78a0 | |
| parent | 56ba0f7b07930ec827328a139e8cf5c25d64d428 (diff) | |
| download | dlfcn-win32-c815879efea297cad9d9fbf76baf972d49dd97fa.tar.gz dlfcn-win32-c815879efea297cad9d9fbf76baf972d49dd97fa.tar.bz2 dlfcn-win32-c815879efea297cad9d9fbf76baf972d49dd97fa.zip | |
Add proper guards for platform code
Do not expect that non-ARM code is automatically X86 code as it does not
have to be. Returns failure (not thunk) in other case.
Make sure that windows test code is not called on non-windows platforms.
Test code tests/test-dladdr.c is written to be validated on any platforms,
including non-windows.
| -rw-r--r-- | src/dlfcn.c | 8 | ||||
| -rw-r--r-- | tests/test-dladdr.c | 9 |
2 files changed, 13 insertions, 4 deletions
diff --git a/src/dlfcn.c b/src/dlfcn.c index 749c35f..522eed0 100644 --- a/src/dlfcn.c +++ b/src/dlfcn.c | |||
| @@ -754,8 +754,10 @@ static BOOL is_import_thunk( const void *addr ) | |||
| 754 | && ( opCode2 & 0xffe003ff ) == 0xf9400210 /* ldr x16, [x16, offset] */ | 754 | && ( opCode2 & 0xffe003ff ) == 0xf9400210 /* ldr x16, [x16, offset] */ |
| 755 | && opCode3 == 0xd61f0200 /* br x16 */ | 755 | && opCode3 == 0xd61f0200 /* br x16 */ |
| 756 | ? TRUE : FALSE; | 756 | ? TRUE : FALSE; |
| 757 | #else | 757 | #elif defined(_M_AMD64) || defined(_M_IX86) || defined(__x86_64__) || defined(__i386__) |
| 758 | return *(USHORT *) addr == 0x25ff ? TRUE : FALSE; | 758 | return *(USHORT *) addr == 0x25ff ? TRUE : FALSE; |
| 759 | #else | ||
| 760 | return FALSE; | ||
| 759 | #endif | 761 | #endif |
| 760 | } | 762 | } |
| 761 | 763 | ||
| @@ -785,7 +787,7 @@ static void *get_address_from_import_address_table( void *iat, DWORD iat_size, c | |||
| 785 | 787 | ||
| 786 | /* Calculate the final address */ | 788 | /* Calculate the final address */ |
| 787 | BYTE *ptr = (BYTE *) ( (ULONG64) thkp & ~0xfffull ) + page + offset; | 789 | BYTE *ptr = (BYTE *) ( (ULONG64) thkp & ~0xfffull ) + page + offset; |
| 788 | #else | 790 | #elif defined(_M_AMD64) || defined(_M_IX86) || defined(__x86_64__) || defined(__i386__) |
| 789 | /* Get offset from thunk table (after instruction 0xff 0x25) | 791 | /* Get offset from thunk table (after instruction 0xff 0x25) |
| 790 | * 4018c8 <_VirtualQuery>: ff 25 4a 8a 00 00 | 792 | * 4018c8 <_VirtualQuery>: ff 25 4a 8a 00 00 |
| 791 | */ | 793 | */ |
| @@ -804,6 +806,8 @@ static void *get_address_from_import_address_table( void *iat, DWORD iat_size, c | |||
| 804 | */ | 806 | */ |
| 805 | BYTE *ptr = (BYTE *) offset; | 807 | BYTE *ptr = (BYTE *) offset; |
| 806 | #endif | 808 | #endif |
| 809 | #else | ||
| 810 | return NULL; | ||
| 807 | #endif | 811 | #endif |
| 808 | 812 | ||
| 809 | if( !is_valid_address( ptr ) || ptr < (BYTE *) iat || ptr > (BYTE *) iat + iat_size ) | 813 | if( !is_valid_address( ptr ) || ptr < (BYTE *) iat || ptr > (BYTE *) iat + iat_size ) |
diff --git a/tests/test-dladdr.c b/tests/test-dladdr.c index 5568f23..aa815b0 100644 --- a/tests/test-dladdr.c +++ b/tests/test-dladdr.c | |||
| @@ -140,6 +140,7 @@ __declspec(dllexport) | |||
| 140 | #endif | 140 | #endif |
| 141 | int main(int argc, char **argv) | 141 | int main(int argc, char **argv) |
| 142 | { | 142 | { |
| 143 | #ifdef _WIN32 | ||
| 143 | #if defined(_M_ARM64) || defined(__aarch64__) | 144 | #if defined(_M_ARM64) || defined(__aarch64__) |
| 144 | /* points to non reachable address */ | 145 | /* points to non reachable address */ |
| 145 | unsigned char zero_thunk_address[12] = { 0x10, 0x00, 0x00, 0x90, 0x10, 0x02, 0x40, 0xF9, 0x00, 0x02, 0x1F, 0xD6 }; | 146 | unsigned char zero_thunk_address[12] = { 0x10, 0x00, 0x00, 0x90, 0x10, 0x02, 0x40, 0xF9, 0x00, 0x02, 0x1F, 0xD6 }; |
| @@ -147,13 +148,16 @@ int main(int argc, char **argv) | |||
| 147 | unsigned char invalid_thunk_address[12] = { 0x10, 0x00, 0x00, 0xb0, 0x10, 0x06, 0x47, 0xF9, 0x00, 0x02, 0x1F, 0xD6 }; | 148 | unsigned char invalid_thunk_address[12] = { 0x10, 0x00, 0x00, 0xb0, 0x10, 0x06, 0x47, 0xF9, 0x00, 0x02, 0x1F, 0xD6 }; |
| 148 | /* no import thunk */ | 149 | /* no import thunk */ |
| 149 | unsigned char no_import_thunk[12] = { 0x11, 0x00, 0x00, 0xb0, 0x31, 0x06, 0x47, 0xF9, 0x20, 0x02, 0x1F, 0xD6 }; | 150 | unsigned char no_import_thunk[12] = { 0x11, 0x00, 0x00, 0xb0, 0x31, 0x06, 0x47, 0xF9, 0x20, 0x02, 0x1F, 0xD6 }; |
| 150 | #else | 151 | #elif defined(_M_AMD64) || defined(_M_IX86) || defined(__x86_64__) || defined(__i386__) |
| 151 | /* points to non reachable address */ | 152 | /* points to non reachable address */ |
| 152 | unsigned char zero_thunk_address[6] = { 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00 }; | 153 | unsigned char zero_thunk_address[6] = { 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00 }; |
| 153 | /* points to executable base */ | 154 | /* points to executable base */ |
| 154 | unsigned char invalid_thunk_address[6] = { 0xFF, 0x25, 0x00, 0x00, 0x40, 0x00 }; | 155 | unsigned char invalid_thunk_address[6] = { 0xFF, 0x25, 0x00, 0x00, 0x40, 0x00 }; |
| 155 | /* no import thunk */ | 156 | /* no import thunk */ |
| 156 | unsigned char no_import_thunk[6] = { 0xFF, 0x26, 0x00, 0x00, 0x40, 0x00 }; | 157 | unsigned char no_import_thunk[6] = { 0xFF, 0x26, 0x00, 0x00, 0x40, 0x00 }; |
| 158 | #else | ||
| 159 | #error "thunk test cases are not defined for this architecture" | ||
| 160 | #endif | ||
| 157 | #endif | 161 | #endif |
| 158 | int result = 0; | 162 | int result = 0; |
| 159 | UNUSED(argv); | 163 | UNUSED(argv); |
| @@ -169,11 +173,12 @@ int main(int argc, char **argv) | |||
| 169 | result |= check_dladdr( "function from executable", (void*)main, "main", Pass ); | 173 | result |= check_dladdr( "function from executable", (void*)main, "main", Pass ); |
| 170 | result |= check_dladdr( "static function from executable", (void*)print_dl_info, "print_dl_info", Fail ); | 174 | result |= check_dladdr( "static function from executable", (void*)print_dl_info, "print_dl_info", Fail ); |
| 171 | result |= check_dladdr( "address with positive offset", ((char*)atoi)+1, "atoi", PassWithDifferentAddress ); | 175 | result |= check_dladdr( "address with positive offset", ((char*)atoi)+1, "atoi", PassWithDifferentAddress ); |
| 176 | |||
| 177 | #ifdef _WIN32 | ||
| 172 | result |= check_dladdr( "zero address from import thunk", zero_thunk_address, "", NoInfo ); | 178 | result |= check_dladdr( "zero address from import thunk", zero_thunk_address, "", NoInfo ); |
| 173 | result |= check_dladdr( "invalid address from import thunk", invalid_thunk_address, "", NoInfo ); | 179 | result |= check_dladdr( "invalid address from import thunk", invalid_thunk_address, "", NoInfo ); |
| 174 | result |= check_dladdr( "no import thunk", no_import_thunk, "", NoInfo ); | 180 | result |= check_dladdr( "no import thunk", no_import_thunk, "", NoInfo ); |
| 175 | 181 | ||
| 176 | #ifdef _WIN32 | ||
| 177 | result |= check_dladdr( "last entry in iat", (void*)VirtualQuery, "VirtualQuery", PassWithDifferentAddress ); | 182 | result |= check_dladdr( "last entry in iat", (void*)VirtualQuery, "VirtualQuery", PassWithDifferentAddress ); |
| 178 | 183 | ||
| 179 | result |= check_dladdr ( "address through import thunk", (void*)GetModuleHandleA, "GetModuleHandleA", PassWithDifferentAddress ); | 184 | result |= check_dladdr ( "address through import thunk", (void*)GetModuleHandleA, "GetModuleHandleA", PassWithDifferentAddress ); |
