ruby-oci8 2.2.3 → 2.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ChangeLog +427 -0
- data/NEWS +335 -42
- data/README.md +20 -9
- data/dist-files +9 -3
- data/docs/bind-array-to-in_cond.md +2 -2
- data/docs/conflicts-local-connections-and-processes.md +7 -4
- data/docs/hanging-after-inactivity.md +63 -0
- data/docs/install-binary-package.md +15 -11
- data/docs/install-full-client.md +18 -21
- data/docs/install-instant-client.md +45 -27
- data/docs/install-on-osx.md +31 -120
- data/docs/ldap-auth-and-function-interposition.md +123 -0
- data/docs/number-type-mapping.md +79 -0
- data/docs/platform-specific-issues.md +17 -50
- data/docs/report-installation-issue.md +3 -0
- data/docs/timeout-parameters.md +3 -0
- data/ext/oci8/apiwrap.c.tmpl +2 -5
- data/ext/oci8/apiwrap.rb +6 -1
- data/ext/oci8/apiwrap.yml +34 -22
- data/ext/oci8/attr.c +4 -2
- data/ext/oci8/bind.c +366 -6
- data/ext/oci8/connection_pool.c +3 -3
- data/ext/oci8/encoding.c +5 -5
- data/ext/oci8/env.c +8 -2
- data/ext/oci8/error.c +24 -16
- data/ext/oci8/extconf.rb +8 -4
- data/ext/oci8/hook_funcs.c +274 -61
- data/ext/oci8/lob.c +31 -75
- data/ext/oci8/metadata.c +2 -2
- data/ext/oci8/object.c +72 -27
- data/ext/oci8/oci8.c +45 -132
- data/ext/oci8/oci8.h +32 -88
- data/ext/oci8/oci8lib.c +178 -38
- data/ext/oci8/ocihandle.c +37 -37
- data/ext/oci8/ocinumber.c +23 -18
- data/ext/oci8/oraconf.rb +158 -339
- data/ext/oci8/oradate.c +19 -19
- data/ext/oci8/plthook.h +10 -0
- data/ext/oci8/plthook_elf.c +433 -268
- data/ext/oci8/plthook_osx.c +40 -9
- data/ext/oci8/plthook_win32.c +9 -0
- data/ext/oci8/stmt.c +52 -17
- data/ext/oci8/win32.c +4 -22
- data/lib/oci8/bindtype.rb +1 -15
- data/lib/oci8/check_load_error.rb +57 -10
- data/lib/oci8/cursor.rb +57 -25
- data/lib/oci8/metadata.rb +9 -1
- data/lib/oci8/object.rb +10 -0
- data/lib/oci8/oci8.rb +33 -28
- data/lib/oci8/oracle_version.rb +11 -1
- data/lib/oci8/properties.rb +22 -0
- data/lib/oci8/version.rb +1 -1
- data/lib/oci8.rb +48 -4
- data/lib/ruby-oci8.rb +0 -3
- data/pre-distclean.rb +1 -3
- data/ruby-oci8.gemspec +3 -8
- data/setup.rb +11 -2
- data/test/README.md +37 -0
- data/test/config.rb +1 -1
- data/test/setup_test_object.sql +21 -13
- data/test/setup_test_package.sql +59 -0
- data/test/test_all.rb +2 -0
- data/test/test_bind_boolean.rb +99 -0
- data/test/test_bind_integer.rb +47 -0
- data/test/test_break.rb +11 -9
- data/test/test_clob.rb +4 -16
- data/test/test_connstr.rb +29 -13
- data/test/test_datetime.rb +8 -3
- data/test/test_object.rb +27 -9
- data/test/test_oci8.rb +170 -46
- data/test/test_oranumber.rb +12 -6
- data/test/test_package_type.rb +15 -3
- data/test/test_properties.rb +17 -0
- metadata +40 -54
- data/docs/osx-install-dev-tools.png +0 -0
- data/test/README +0 -42
data/ext/oci8/plthook_elf.c
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
*
|
7
7
|
* ------------------------------------------------------
|
8
8
|
*
|
9
|
-
* Copyright 2013-
|
9
|
+
* Copyright 2013-2016 Kubo Takehiro <kubo@jiubao.org>
|
10
10
|
*
|
11
11
|
* Redistribution and use in source and binary forms, with or without modification, are
|
12
12
|
* permitted provided that the following conditions are met:
|
@@ -33,22 +33,30 @@
|
|
33
33
|
* or implied, of the authors.
|
34
34
|
*
|
35
35
|
*/
|
36
|
+
#if defined(__sun) && defined(_XOPEN_SOURCE) && !defined(__EXTENSIONS__)
|
37
|
+
#define __EXTENSIONS__
|
38
|
+
#endif
|
39
|
+
#if defined(__linux__) && !defined(_GNU_SOURCE)
|
36
40
|
#define _GNU_SOURCE
|
41
|
+
#endif
|
37
42
|
#include <stdio.h>
|
38
43
|
#include <stdarg.h>
|
39
44
|
#include <stdlib.h>
|
40
45
|
#include <unistd.h>
|
41
46
|
#include <string.h>
|
42
47
|
#include <limits.h>
|
43
|
-
#include <sys/
|
44
|
-
#include <sys/stat.h>
|
45
|
-
#include <fcntl.h>
|
48
|
+
#include <sys/mman.h>
|
46
49
|
#include <errno.h>
|
47
50
|
#include <dlfcn.h>
|
48
51
|
#ifdef __sun
|
49
|
-
#include <
|
52
|
+
#include <sys/auxv.h>
|
50
53
|
#define ELF_TARGET_ALL
|
51
54
|
#endif /* __sun */
|
55
|
+
#ifdef __FreeBSD__
|
56
|
+
#include <sys/types.h>
|
57
|
+
#include <sys/user.h>
|
58
|
+
#include <libutil.h>
|
59
|
+
#endif
|
52
60
|
#include <elf.h>
|
53
61
|
#include <link.h>
|
54
62
|
#include "plthook.h"
|
@@ -57,39 +65,47 @@
|
|
57
65
|
#define __attribute__(arg)
|
58
66
|
#endif
|
59
67
|
|
60
|
-
#if defined
|
61
|
-
#define ELF_OSABI ELFOSABI_SYSV
|
62
|
-
#elif defined __sun
|
63
|
-
#define ELF_OSABI ELFOSABI_SOLARIS
|
64
|
-
#elif defined __FreeBSD__
|
65
|
-
#define ELF_OSABI ELFOSABI_FREEBSD
|
66
|
-
#if defined __i386__ && __ELF_WORD_SIZE == 64
|
68
|
+
#if defined __FreeBSD__ && defined __i386__ && __ELF_WORD_SIZE == 64
|
67
69
|
#error 32-bit application on 64-bit OS is not supported.
|
68
70
|
#endif
|
69
|
-
|
70
|
-
#
|
71
|
+
|
72
|
+
#if !defined(R_X86_64_JUMP_SLOT) && defined(R_X86_64_JMP_SLOT)
|
73
|
+
#define R_X86_64_JUMP_SLOT R_X86_64_JMP_SLOT
|
71
74
|
#endif
|
72
75
|
|
73
76
|
#if defined __x86_64__ || defined __x86_64
|
74
|
-
#define ELF_DATA ELFDATA2LSB
|
75
|
-
#define E_MACHINE EM_X86_64
|
76
|
-
#ifdef R_X86_64_JUMP_SLOT
|
77
77
|
#define R_JUMP_SLOT R_X86_64_JUMP_SLOT
|
78
|
-
#else
|
79
|
-
#define R_JUMP_SLOT R_X86_64_JMP_SLOT
|
80
|
-
#endif
|
81
|
-
#define SHT_PLT_REL SHT_RELA
|
82
78
|
#define Elf_Plt_Rel Elf_Rela
|
83
|
-
#define
|
79
|
+
#define PLT_DT_REL DT_RELA
|
80
|
+
#define R_GLOBAL_DATA R_X86_64_GLOB_DAT
|
84
81
|
#elif defined __i386__ || defined __i386
|
85
|
-
#define ELF_DATA ELFDATA2LSB
|
86
|
-
#define E_MACHINE EM_386
|
87
82
|
#define R_JUMP_SLOT R_386_JMP_SLOT
|
88
|
-
#define SHT_PLT_REL SHT_REL
|
89
83
|
#define Elf_Plt_Rel Elf_Rel
|
90
|
-
#define
|
84
|
+
#define PLT_DT_REL DT_REL
|
85
|
+
#define R_GLOBAL_DATA R_386_GLOB_DAT
|
86
|
+
#elif defined __arm__ || defined __arm
|
87
|
+
#define R_JUMP_SLOT R_ARM_JUMP_SLOT
|
88
|
+
#define Elf_Plt_Rel Elf_Rel
|
89
|
+
#elif defined __aarch64__ || defined __aarch64 /* ARM64 */
|
90
|
+
#define R_JUMP_SLOT R_AARCH64_JUMP_SLOT
|
91
|
+
#define Elf_Plt_Rel Elf_Rela
|
92
|
+
#elif defined __powerpc64__
|
93
|
+
#define R_JUMP_SLOT R_PPC64_JMP_SLOT
|
94
|
+
#define Elf_Plt_Rel Elf_Rela
|
95
|
+
#elif defined __powerpc__
|
96
|
+
#define R_JUMP_SLOT R_PPC_JMP_SLOT
|
97
|
+
#define Elf_Plt_Rel Elf_Rela
|
98
|
+
#elif 0 /* disabled because not tested */ && (defined __sparcv9 || defined __sparc_v9__)
|
99
|
+
#define R_JUMP_SLOT R_SPARC_JMP_SLOT
|
100
|
+
#define Elf_Plt_Rel Elf_Rela
|
101
|
+
#elif 0 /* disabled because not tested */ && (defined __sparc || defined __sparc__)
|
102
|
+
#define R_JUMP_SLOT R_SPARC_JMP_SLOT
|
103
|
+
#define Elf_Plt_Rel Elf_Rela
|
104
|
+
#elif 0 /* disabled because not tested */ && (defined __ia64 || defined __ia64__)
|
105
|
+
#define R_JUMP_SLOT R_IA64_IPLTMSB
|
106
|
+
#define Elf_Plt_Rel Elf_Rela
|
91
107
|
#else
|
92
|
-
#error
|
108
|
+
#error unsupported OS
|
93
109
|
#endif
|
94
110
|
|
95
111
|
#if defined __LP64__
|
@@ -97,12 +113,16 @@
|
|
97
113
|
#define ELF_CLASS ELFCLASS64
|
98
114
|
#endif
|
99
115
|
#define SIZE_T_FMT "lu"
|
116
|
+
#define ELF_WORD_FMT "u"
|
117
|
+
#define ELF_XWORD_FMT "lu"
|
118
|
+
#define ELF_SXWORD_FMT "ld"
|
100
119
|
#define Elf_Half Elf64_Half
|
101
|
-
#define
|
120
|
+
#define Elf_Xword Elf64_Xword
|
121
|
+
#define Elf_Sxword Elf64_Sxword
|
102
122
|
#define Elf_Ehdr Elf64_Ehdr
|
103
123
|
#define Elf_Phdr Elf64_Phdr
|
104
|
-
#define Elf_Shdr Elf64_Shdr
|
105
124
|
#define Elf_Sym Elf64_Sym
|
125
|
+
#define Elf_Dyn Elf64_Dyn
|
106
126
|
#define Elf_Rel Elf64_Rel
|
107
127
|
#define Elf_Rela Elf64_Rela
|
108
128
|
#ifndef ELF_R_SYM
|
@@ -116,12 +136,22 @@
|
|
116
136
|
#define ELF_CLASS ELFCLASS32
|
117
137
|
#endif
|
118
138
|
#define SIZE_T_FMT "u"
|
139
|
+
#ifdef __sun
|
140
|
+
#define ELF_WORD_FMT "lu"
|
141
|
+
#define ELF_XWORD_FMT "lu"
|
142
|
+
#define ELF_SXWORD_FMT "ld"
|
143
|
+
#else
|
144
|
+
#define ELF_WORD_FMT "u"
|
145
|
+
#define ELF_XWORD_FMT "u"
|
146
|
+
#define ELF_SXWORD_FMT "d"
|
147
|
+
#endif
|
119
148
|
#define Elf_Half Elf32_Half
|
120
|
-
#define
|
149
|
+
#define Elf_Xword Elf32_Word
|
150
|
+
#define Elf_Sxword Elf32_Sword
|
121
151
|
#define Elf_Ehdr Elf32_Ehdr
|
122
152
|
#define Elf_Phdr Elf32_Phdr
|
123
|
-
#define Elf_Shdr Elf32_Shdr
|
124
153
|
#define Elf_Sym Elf32_Sym
|
154
|
+
#define Elf_Dyn Elf32_Dyn
|
125
155
|
#define Elf_Rel Elf32_Rel
|
126
156
|
#define Elf_Rela Elf32_Rela
|
127
157
|
#ifndef ELF_R_SYM
|
@@ -132,29 +162,41 @@
|
|
132
162
|
#endif
|
133
163
|
#endif /* __LP64__ */
|
134
164
|
|
165
|
+
#if defined(PT_GNU_RELRO) && !defined(__sun)
|
166
|
+
#define SUPPORT_RELRO /* RELRO (RELocation Read-Only) */
|
167
|
+
#if !defined(DF_1_NOW) && defined(DF_1_BIND_NOW)
|
168
|
+
#define DF_1_NOW DF_1_BIND_NOW
|
169
|
+
#endif
|
170
|
+
#endif
|
171
|
+
|
135
172
|
struct plthook {
|
136
|
-
const char *base;
|
137
|
-
const Elf_Phdr *phdr;
|
138
|
-
size_t phnum;
|
139
|
-
Elf_Shdr *shdr;
|
140
|
-
size_t shnum;
|
141
|
-
char *shstrtab;
|
142
|
-
size_t shstrtab_size;
|
143
173
|
const Elf_Sym *dynsym;
|
144
|
-
size_t dynsym_cnt;
|
145
174
|
const char *dynstr;
|
146
175
|
size_t dynstr_size;
|
176
|
+
const char *plt_addr_base;
|
147
177
|
const Elf_Plt_Rel *plt;
|
148
178
|
size_t plt_cnt;
|
179
|
+
Elf_Xword r_type;
|
180
|
+
#ifdef SUPPORT_RELRO
|
181
|
+
const char *relro_start;
|
182
|
+
const char *relro_end;
|
183
|
+
#endif
|
149
184
|
};
|
150
185
|
|
151
186
|
static char errmsg[512];
|
152
187
|
|
188
|
+
#ifdef SUPPORT_RELRO
|
189
|
+
static size_t page_size;
|
190
|
+
#endif
|
191
|
+
|
153
192
|
static int plthook_open_executable(plthook_t **plthook_out);
|
154
193
|
static int plthook_open_shared_library(plthook_t **plthook_out, const char *filename);
|
155
|
-
static
|
194
|
+
static const Elf_Dyn *find_dyn_by_tag(const Elf_Dyn *dyn, Elf_Sxword tag);
|
195
|
+
#ifdef SUPPORT_RELRO
|
196
|
+
static int set_relro_members(plthook_t *plthook, struct link_map *lmap);
|
197
|
+
#endif
|
198
|
+
static int plthook_open_real(plthook_t **plthook_out, struct link_map *lmap);
|
156
199
|
static int check_elf_header(const Elf_Ehdr *ehdr);
|
157
|
-
static int find_section(plthook_t *image, const char *name, const Elf_Shdr **out);
|
158
200
|
static void set_errmsg(const char *fmt, ...) __attribute__((__format__ (__printf__, 1, 2)));
|
159
201
|
|
160
202
|
int plthook_open(plthook_t **plthook_out, const char *filename)
|
@@ -167,69 +209,71 @@ int plthook_open(plthook_t **plthook_out, const char *filename)
|
|
167
209
|
}
|
168
210
|
}
|
169
211
|
|
212
|
+
int plthook_open_by_handle(plthook_t **plthook_out, void *hndl)
|
213
|
+
{
|
214
|
+
struct link_map *lmap = NULL;
|
215
|
+
|
216
|
+
if (hndl == NULL) {
|
217
|
+
set_errmsg("NULL handle");
|
218
|
+
return PLTHOOK_FILE_NOT_FOUND;
|
219
|
+
}
|
220
|
+
if (dlinfo(hndl, RTLD_DI_LINKMAP, &lmap) != 0) {
|
221
|
+
set_errmsg("dlinfo error");
|
222
|
+
return PLTHOOK_FILE_NOT_FOUND;
|
223
|
+
}
|
224
|
+
return plthook_open_real(plthook_out, lmap);
|
225
|
+
}
|
226
|
+
|
170
227
|
int plthook_open_by_address(plthook_t **plthook_out, void *address)
|
171
228
|
{
|
229
|
+
#if defined __FreeBSD__
|
230
|
+
return PLTHOOK_NOT_IMPLEMENTED;
|
231
|
+
#else
|
172
232
|
Dl_info info;
|
233
|
+
struct link_map *lmap = NULL;
|
173
234
|
|
174
235
|
*plthook_out = NULL;
|
175
|
-
if (
|
236
|
+
if (dladdr1(address, &info, (void**)&lmap, RTLD_DL_LINKMAP) == 0) {
|
176
237
|
set_errmsg("dladdr error");
|
177
238
|
return PLTHOOK_FILE_NOT_FOUND;
|
178
239
|
}
|
179
|
-
return plthook_open_real(plthook_out,
|
240
|
+
return plthook_open_real(plthook_out, lmap);
|
241
|
+
#endif
|
180
242
|
}
|
181
243
|
|
182
244
|
static int plthook_open_executable(plthook_t **plthook_out)
|
183
245
|
{
|
184
246
|
#if defined __linux__
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
247
|
+
return plthook_open_real(plthook_out, _r_debug.r_map);
|
248
|
+
#elif defined __sun
|
249
|
+
const char *auxv_file = "/proc/self/auxv";
|
250
|
+
#define NUM_AUXV_CNT 10
|
251
|
+
FILE *fp = fopen(auxv_file, "r");
|
252
|
+
auxv_t auxv;
|
253
|
+
struct r_debug *r_debug = NULL;
|
189
254
|
|
190
255
|
if (fp == NULL) {
|
191
|
-
set_errmsg("Could not open
|
256
|
+
set_errmsg("Could not open %s: %s", auxv_file,
|
192
257
|
strerror(errno));
|
193
258
|
return PLTHOOK_INTERNAL_ERROR;
|
194
259
|
}
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
260
|
+
while (fread(&auxv, sizeof(auxv_t), 1, fp) == 1) {
|
261
|
+
if (auxv.a_type == AT_SUN_LDDATA) {
|
262
|
+
r_debug = (struct r_debug *)auxv.a_un.a_ptr;
|
263
|
+
break;
|
264
|
+
}
|
200
265
|
}
|
201
266
|
fclose(fp);
|
202
|
-
if (
|
203
|
-
set_errmsg("
|
204
|
-
return PLTHOOK_INTERNAL_ERROR;
|
205
|
-
}
|
206
|
-
return plthook_open_real(plthook_out, (const char*)base, "/proc/self/exe");
|
207
|
-
#elif defined __sun
|
208
|
-
prmap_t prmap;
|
209
|
-
pid_t pid = getpid();
|
210
|
-
char fname[128];
|
211
|
-
int fd;
|
212
|
-
|
213
|
-
sprintf(fname, "/proc/%d/map", pid);
|
214
|
-
fd = open(fname, O_RDONLY);
|
215
|
-
if (fd == -1) {
|
216
|
-
set_errmsg("Could not open %s: %s", fname,
|
217
|
-
strerror(errno));
|
267
|
+
if (r_debug == NULL) {
|
268
|
+
set_errmsg("Could not find r_debug");
|
218
269
|
return PLTHOOK_INTERNAL_ERROR;
|
219
270
|
}
|
220
|
-
|
221
|
-
set_errmsg("Could not read %s: %s", fname,
|
222
|
-
strerror(errno));
|
223
|
-
close(fd);
|
224
|
-
return PLTHOOK_INTERNAL_ERROR;
|
225
|
-
}
|
226
|
-
close(fd);
|
227
|
-
sprintf(fname, "/proc/%d/object/a.out", pid);
|
228
|
-
return plthook_open_real(plthook_out, (const char*)prmap.pr_vaddr, fname);
|
271
|
+
return plthook_open_real(plthook_out, r_debug->r_map);
|
229
272
|
#elif defined __FreeBSD__
|
230
273
|
return plthook_open_shared_library(plthook_out, NULL);
|
231
274
|
#else
|
232
|
-
|
275
|
+
set_errmsg("Opening the main program is not supported on this platform.");
|
276
|
+
return PLTHOOK_NOT_IMPLEMENTED;
|
233
277
|
#endif
|
234
278
|
}
|
235
279
|
|
@@ -248,161 +292,339 @@ static int plthook_open_shared_library(plthook_t **plthook_out, const char *file
|
|
248
292
|
return PLTHOOK_FILE_NOT_FOUND;
|
249
293
|
}
|
250
294
|
dlclose(hndl);
|
251
|
-
return plthook_open_real(plthook_out,
|
295
|
+
return plthook_open_real(plthook_out, lmap);
|
252
296
|
}
|
253
297
|
|
254
|
-
static
|
298
|
+
static const Elf_Dyn *find_dyn_by_tag(const Elf_Dyn *dyn, Elf_Sxword tag)
|
255
299
|
{
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
300
|
+
while (dyn->d_tag != DT_NULL) {
|
301
|
+
if (dyn->d_tag == tag) {
|
302
|
+
return dyn;
|
303
|
+
}
|
304
|
+
dyn++;
|
305
|
+
}
|
306
|
+
return NULL;
|
307
|
+
}
|
263
308
|
|
264
|
-
|
265
|
-
|
266
|
-
|
309
|
+
#ifdef SUPPORT_RELRO
|
310
|
+
#if defined __linux__
|
311
|
+
static const char *get_mapped_file(const void *address, char *buf, int *err)
|
312
|
+
{
|
313
|
+
unsigned long addr = (unsigned long)address;
|
314
|
+
FILE *fp;
|
315
|
+
|
316
|
+
fp = fopen("/proc/self/maps", "r");
|
317
|
+
if (fp == NULL) {
|
318
|
+
set_errmsg("failed to open /proc/self/maps");
|
319
|
+
*err = PLTHOOK_INTERNAL_ERROR;
|
320
|
+
return NULL;
|
267
321
|
}
|
322
|
+
while (fgets(buf, PATH_MAX, fp) != NULL) {
|
323
|
+
unsigned long start, end;
|
324
|
+
int offset = 0;
|
268
325
|
|
269
|
-
|
270
|
-
|
271
|
-
|
326
|
+
sscanf(buf, "%lx-%lx %*s %*x %*x:%*x %*u %n", &start, &end, &offset);
|
327
|
+
if (offset == 0) {
|
328
|
+
continue;
|
329
|
+
}
|
330
|
+
if (start < addr && addr < end) {
|
331
|
+
char *p = buf + offset;
|
332
|
+
while (*p == ' ') {
|
333
|
+
p++;
|
334
|
+
}
|
335
|
+
if (*p != '/') {
|
336
|
+
continue;
|
337
|
+
}
|
338
|
+
p[strlen(p) - 1] = '\0'; /* remove '\n' */
|
339
|
+
fclose(fp);
|
340
|
+
return p;
|
341
|
+
}
|
272
342
|
}
|
343
|
+
fclose(fp);
|
344
|
+
set_errmsg("Could not find a mapped file reagion containing %p", address);
|
345
|
+
*err = PLTHOOK_INTERNAL_ERROR;
|
346
|
+
return NULL;
|
347
|
+
}
|
348
|
+
#elif defined __FreeBSD__
|
349
|
+
static const char *get_mapped_file(const void *address, char *buf, int *err)
|
350
|
+
{
|
351
|
+
uint64_t addr = (uint64_t)address;
|
352
|
+
struct kinfo_vmentry *top;
|
353
|
+
int i, cnt;
|
354
|
+
|
355
|
+
top = kinfo_getvmmap(getpid(), &cnt);
|
356
|
+
if (top == NULL) {
|
357
|
+
fprintf(stderr, "failed to call kinfo_getvmmap()\n");
|
358
|
+
*err = PLTHOOK_INTERNAL_ERROR;
|
359
|
+
return NULL;
|
360
|
+
}
|
361
|
+
for (i = 0; i < cnt; i++) {
|
362
|
+
struct kinfo_vmentry *kve = top + i;
|
363
|
+
|
364
|
+
if (kve->kve_start < addr && addr < kve->kve_end) {
|
365
|
+
strncpy(buf, kve->kve_path, PATH_MAX);
|
366
|
+
free(top);
|
367
|
+
return buf;
|
368
|
+
}
|
369
|
+
}
|
370
|
+
free(top);
|
371
|
+
set_errmsg("Could not find a mapped file reagion containing %p", address);
|
372
|
+
*err = PLTHOOK_INTERNAL_ERROR;
|
373
|
+
return NULL;
|
374
|
+
}
|
375
|
+
#else
|
376
|
+
static const char *get_mapped_file(const void *address, char *buf, int *err)
|
377
|
+
{
|
378
|
+
set_errmsg("Could not find a mapped file reagion containing %p", address);
|
379
|
+
*err = PLTHOOK_INTERNAL_ERROR;
|
380
|
+
return NULL;
|
381
|
+
}
|
382
|
+
#endif
|
273
383
|
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
384
|
+
static int set_relro_members(plthook_t *plthook, struct link_map *lmap)
|
385
|
+
{
|
386
|
+
char fnamebuf[PATH_MAX];
|
387
|
+
const char *fname;
|
388
|
+
FILE *fp;
|
389
|
+
Elf_Ehdr ehdr;
|
390
|
+
Elf_Half idx;
|
391
|
+
int rv;
|
392
|
+
|
393
|
+
if (lmap->l_name[0] == '/') {
|
394
|
+
fname = lmap->l_name;
|
395
|
+
} else {
|
396
|
+
int err;
|
397
|
+
|
398
|
+
fname = get_mapped_file(plthook->dynstr, fnamebuf, &err);
|
399
|
+
if (fname == NULL) {
|
400
|
+
return err;
|
401
|
+
}
|
402
|
+
}
|
403
|
+
fp = fopen(fname, "r");
|
404
|
+
if (fp == NULL) {
|
405
|
+
set_errmsg("failed to open %s", fname);
|
406
|
+
return PLTHOOK_INTERNAL_ERROR;
|
407
|
+
}
|
408
|
+
if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1) {
|
409
|
+
set_errmsg("failed to read the ELF header.");
|
410
|
+
fclose(fp);
|
411
|
+
return PLTHOOK_INVALID_FILE_FORMAT;
|
412
|
+
}
|
413
|
+
rv = check_elf_header(&ehdr);
|
414
|
+
if (rv != 0) {
|
415
|
+
fclose(fp);
|
416
|
+
return rv;
|
278
417
|
}
|
279
418
|
|
280
|
-
|
281
|
-
|
419
|
+
fseek(fp, ehdr.e_phoff, SEEK_SET);
|
420
|
+
|
421
|
+
for (idx = 0; idx < ehdr.e_phnum; idx++) {
|
422
|
+
Elf_Phdr phdr;
|
423
|
+
|
424
|
+
if (fread(&phdr, sizeof(phdr), 1, fp) != 1) {
|
425
|
+
set_errmsg("failed to read the program header table.");
|
426
|
+
fclose(fp);
|
427
|
+
return PLTHOOK_INVALID_FILE_FORMAT;
|
428
|
+
}
|
429
|
+
if (phdr.p_type == PT_GNU_RELRO) {
|
430
|
+
plthook->relro_start = plthook->plt_addr_base + phdr.p_vaddr;
|
431
|
+
plthook->relro_end = plthook->relro_start + phdr.p_memsz;
|
432
|
+
break;
|
433
|
+
}
|
434
|
+
}
|
435
|
+
fclose(fp);
|
436
|
+
return 0;
|
437
|
+
}
|
438
|
+
#endif
|
439
|
+
|
440
|
+
static int plthook_open_real(plthook_t **plthook_out, struct link_map *lmap)
|
441
|
+
{
|
442
|
+
plthook_t plthook = {NULL,};
|
443
|
+
const Elf_Dyn *dyn;
|
444
|
+
const char *dyn_addr_base = NULL;
|
445
|
+
|
446
|
+
#if defined __linux__
|
447
|
+
plthook.plt_addr_base = (char*)lmap->l_addr;
|
448
|
+
#elif defined __FreeBSD__ || defined __sun
|
449
|
+
const Elf_Ehdr *ehdr = (const Elf_Ehdr*)lmap->l_addr;
|
450
|
+
int rv = check_elf_header(ehdr);
|
282
451
|
if (rv != 0) {
|
283
|
-
|
452
|
+
return rv;
|
284
453
|
}
|
285
454
|
if (ehdr->e_type == ET_DYN) {
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
if (plthook->shdr == NULL) {
|
299
|
-
set_errmsg("failed to allocate memory: %" SIZE_T_FMT " bytes", shdr_size);
|
300
|
-
rv = PLTHOOK_OUT_OF_MEMORY;
|
301
|
-
goto error_exit;
|
302
|
-
}
|
303
|
-
offset = ehdr->e_shoff;
|
304
|
-
if ((rv = lseek(fd, offset, SEEK_SET)) != offset) {
|
305
|
-
set_errmsg("failed to seek to the section header table.");
|
306
|
-
rv = PLTHOOK_INVALID_FILE_FORMAT;
|
307
|
-
goto error_exit;
|
308
|
-
}
|
309
|
-
if (read(fd, plthook->shdr, shdr_size) != shdr_size) {
|
310
|
-
set_errmsg("failed to read the section header table.");
|
311
|
-
rv = PLTHOOK_INVALID_FILE_FORMAT;
|
312
|
-
goto error_exit;
|
313
|
-
}
|
314
|
-
plthook->shnum = ehdr->e_shnum;
|
315
|
-
plthook->shstrtab_size = plthook->shdr[ehdr->e_shstrndx].sh_size;
|
316
|
-
plthook->shstrtab = malloc(plthook->shstrtab_size);
|
317
|
-
if (plthook->shstrtab == NULL) {
|
318
|
-
set_errmsg("failed to allocate memory: %" SIZE_T_FMT " bytes", plthook->shstrtab_size);
|
319
|
-
rv = PLTHOOK_OUT_OF_MEMORY;
|
320
|
-
goto error_exit;
|
321
|
-
}
|
322
|
-
offset = plthook->shdr[ehdr->e_shstrndx].sh_offset;
|
323
|
-
if (lseek(fd, offset, SEEK_SET) != offset) {
|
324
|
-
set_errmsg("failed to seek to the section header string table.");
|
325
|
-
rv = PLTHOOK_INVALID_FILE_FORMAT;
|
326
|
-
goto error_exit;
|
327
|
-
}
|
328
|
-
if (read(fd, plthook->shstrtab, plthook->shstrtab_size) != plthook->shstrtab_size) {
|
329
|
-
set_errmsg("failed to read the section header string table.");
|
330
|
-
rv = PLTHOOK_INVALID_FILE_FORMAT;
|
331
|
-
goto error_exit;
|
332
|
-
}
|
333
|
-
close(fd);
|
334
|
-
fd = -1;
|
335
|
-
|
336
|
-
rv = find_section(plthook, ".dynsym", &shdr);
|
337
|
-
if (rv != 0) {
|
338
|
-
goto error_exit;
|
455
|
+
dyn_addr_base = (const char*)lmap->l_addr;
|
456
|
+
plthook.plt_addr_base = (const char*)lmap->l_addr;
|
457
|
+
}
|
458
|
+
#else
|
459
|
+
#error unsupported OS
|
460
|
+
#endif
|
461
|
+
|
462
|
+
/* get .dynsym section */
|
463
|
+
dyn = find_dyn_by_tag(lmap->l_ld, DT_SYMTAB);
|
464
|
+
if (dyn == NULL) {
|
465
|
+
set_errmsg("failed to find DT_SYMTAB");
|
466
|
+
return PLTHOOK_INTERNAL_ERROR;
|
339
467
|
}
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
468
|
+
plthook.dynsym = (const Elf_Sym*)(dyn_addr_base + dyn->d_un.d_ptr);
|
469
|
+
|
470
|
+
/* Check sizeof(Elf_Sym) */
|
471
|
+
dyn = find_dyn_by_tag(lmap->l_ld, DT_SYMENT);
|
472
|
+
if (dyn == NULL) {
|
473
|
+
set_errmsg("failed to find DT_SYMTAB");
|
474
|
+
return PLTHOOK_INTERNAL_ERROR;
|
344
475
|
}
|
345
|
-
if (
|
346
|
-
set_errmsg("
|
347
|
-
|
348
|
-
rv = PLTHOOK_INVALID_FILE_FORMAT;
|
349
|
-
goto error_exit;
|
476
|
+
if (dyn->d_un.d_val != sizeof(Elf_Sym)) {
|
477
|
+
set_errmsg("DT_SYMENT size %" ELF_XWORD_FMT " != %" SIZE_T_FMT, dyn->d_un.d_val, sizeof(Elf_Sym));
|
478
|
+
return PLTHOOK_INTERNAL_ERROR;
|
350
479
|
}
|
351
|
-
plthook->dynsym = (const Elf_Sym*)(plthook->base + shdr->sh_addr);
|
352
|
-
plthook->dynsym_cnt = shdr->sh_size / shdr->sh_entsize;
|
353
480
|
|
354
|
-
|
355
|
-
|
356
|
-
|
481
|
+
/* get .dynstr section */
|
482
|
+
dyn = find_dyn_by_tag(lmap->l_ld, DT_STRTAB);
|
483
|
+
if (dyn == NULL) {
|
484
|
+
set_errmsg("failed to find DT_STRTAB");
|
485
|
+
return PLTHOOK_INTERNAL_ERROR;
|
357
486
|
}
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
487
|
+
plthook.dynstr = dyn_addr_base + dyn->d_un.d_ptr;
|
488
|
+
|
489
|
+
/* get .dynstr size */
|
490
|
+
dyn = find_dyn_by_tag(lmap->l_ld, DT_STRSZ);
|
491
|
+
if (dyn == NULL) {
|
492
|
+
set_errmsg("failed to find DT_STRSZ");
|
493
|
+
return PLTHOOK_INTERNAL_ERROR;
|
362
494
|
}
|
363
|
-
plthook
|
364
|
-
plthook->dynstr_size = shdr->sh_size;
|
495
|
+
plthook.dynstr_size = dyn->d_un.d_val;
|
365
496
|
|
366
|
-
|
367
|
-
|
368
|
-
|
497
|
+
/* get .rela.plt or .rel.plt section */
|
498
|
+
dyn = find_dyn_by_tag(lmap->l_ld, DT_JMPREL);
|
499
|
+
plthook.r_type = R_JUMP_SLOT;
|
500
|
+
#ifdef PLT_DT_REL
|
501
|
+
if (dyn == NULL) {
|
502
|
+
/* get .rela.dyn or .rel.dyn section */
|
503
|
+
dyn = find_dyn_by_tag(lmap->l_ld, PLT_DT_REL);
|
504
|
+
plthook.r_type = R_GLOBAL_DATA;
|
369
505
|
}
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
506
|
+
#endif
|
507
|
+
if (dyn == NULL) {
|
508
|
+
set_errmsg("failed to find DT_JMPREL");
|
509
|
+
return PLTHOOK_INTERNAL_ERROR;
|
374
510
|
}
|
375
|
-
plthook
|
376
|
-
|
511
|
+
plthook.plt = (const Elf_Plt_Rel *)(dyn_addr_base + dyn->d_un.d_ptr);
|
512
|
+
|
513
|
+
if (plthook.r_type == R_JUMP_SLOT) {
|
514
|
+
/* get total size of .rela.plt or .rel.plt */
|
515
|
+
dyn = find_dyn_by_tag(lmap->l_ld, DT_PLTRELSZ);
|
516
|
+
if (dyn == NULL) {
|
517
|
+
set_errmsg("failed to find DT_PLTRELSZ");
|
518
|
+
return PLTHOOK_INTERNAL_ERROR;
|
519
|
+
}
|
377
520
|
|
378
|
-
|
521
|
+
plthook.plt_cnt = dyn->d_un.d_val / sizeof(Elf_Plt_Rel);
|
522
|
+
#ifdef PLT_DT_REL
|
523
|
+
} else {
|
524
|
+
int total_size_tag = PLT_DT_REL == DT_RELA ? DT_RELASZ : DT_RELSZ;
|
525
|
+
int elem_size_tag = PLT_DT_REL == DT_RELA ? DT_RELAENT : DT_RELENT;
|
526
|
+
size_t total_size, elem_size;
|
527
|
+
|
528
|
+
dyn = find_dyn_by_tag(lmap->l_ld, total_size_tag);
|
529
|
+
if (dyn == NULL) {
|
530
|
+
set_errmsg("failed to find 0x%x", total_size_tag);
|
531
|
+
return PLTHOOK_INTERNAL_ERROR;
|
532
|
+
}
|
533
|
+
total_size = dyn->d_un.d_ptr;
|
534
|
+
|
535
|
+
dyn = find_dyn_by_tag(lmap->l_ld, elem_size_tag);
|
536
|
+
if (dyn == NULL) {
|
537
|
+
set_errmsg("failed to find 0x%x", elem_size_tag);
|
538
|
+
return PLTHOOK_INTERNAL_ERROR;
|
539
|
+
}
|
540
|
+
elem_size = dyn->d_un.d_ptr;
|
541
|
+
plthook.plt_cnt = total_size / elem_size;
|
542
|
+
#endif
|
543
|
+
}
|
544
|
+
|
545
|
+
#ifdef SUPPORT_RELRO
|
546
|
+
dyn = find_dyn_by_tag(lmap->l_ld, DT_FLAGS_1);
|
547
|
+
if (dyn != NULL && (dyn->d_un.d_val & DF_1_NOW)) {
|
548
|
+
int rv = set_relro_members(&plthook, lmap);
|
549
|
+
if (rv != 0) {
|
550
|
+
return rv;
|
551
|
+
}
|
552
|
+
if (page_size == 0) {
|
553
|
+
page_size = sysconf(_SC_PAGESIZE);
|
554
|
+
}
|
555
|
+
}
|
556
|
+
#endif
|
557
|
+
|
558
|
+
*plthook_out = malloc(sizeof(plthook_t));
|
559
|
+
if (*plthook_out == NULL) {
|
560
|
+
set_errmsg("failed to allocate memory: %" SIZE_T_FMT " bytes", sizeof(plthook_t));
|
561
|
+
return PLTHOOK_OUT_OF_MEMORY;
|
562
|
+
}
|
563
|
+
**plthook_out = plthook;
|
379
564
|
return 0;
|
380
|
-
|
381
|
-
|
382
|
-
|
565
|
+
}
|
566
|
+
|
567
|
+
static int check_elf_header(const Elf_Ehdr *ehdr)
|
568
|
+
{
|
569
|
+
static const unsigned short s = 1;
|
570
|
+
/* Check endianness at runtime. */
|
571
|
+
unsigned char elfdata = (*(const char*)&s) ? ELFDATA2LSB : ELFDATA2MSB;
|
572
|
+
|
573
|
+
if (ehdr == NULL) {
|
574
|
+
set_errmsg("invalid elf header address: NULL");
|
575
|
+
return PLTHOOK_INTERNAL_ERROR;
|
383
576
|
}
|
384
|
-
|
385
|
-
|
577
|
+
|
578
|
+
if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) {
|
579
|
+
set_errmsg("invalid file signature: 0x%02x,0x%02x,0x%02x,0x%02x",
|
580
|
+
ehdr->e_ident[0], ehdr->e_ident[1], ehdr->e_ident[2], ehdr->e_ident[3]);
|
581
|
+
return PLTHOOK_INVALID_FILE_FORMAT;
|
582
|
+
}
|
583
|
+
if (ehdr->e_ident[EI_CLASS] != ELF_CLASS) {
|
584
|
+
set_errmsg("invalid elf class: 0x%02x", ehdr->e_ident[EI_CLASS]);
|
585
|
+
return PLTHOOK_INVALID_FILE_FORMAT;
|
586
|
+
}
|
587
|
+
if (ehdr->e_ident[EI_DATA] != elfdata) {
|
588
|
+
set_errmsg("invalid elf data: 0x%02x", ehdr->e_ident[EI_DATA]);
|
589
|
+
return PLTHOOK_INVALID_FILE_FORMAT;
|
590
|
+
}
|
591
|
+
if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) {
|
592
|
+
set_errmsg("invalid elf version: 0x%02x", ehdr->e_ident[EI_VERSION]);
|
593
|
+
return PLTHOOK_INVALID_FILE_FORMAT;
|
594
|
+
}
|
595
|
+
if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) {
|
596
|
+
set_errmsg("invalid file type: 0x%04x", ehdr->e_type);
|
597
|
+
return PLTHOOK_INVALID_FILE_FORMAT;
|
598
|
+
}
|
599
|
+
if (ehdr->e_version != EV_CURRENT) {
|
600
|
+
set_errmsg("invalid object file version: %" ELF_WORD_FMT, ehdr->e_version);
|
601
|
+
return PLTHOOK_INVALID_FILE_FORMAT;
|
602
|
+
}
|
603
|
+
if (ehdr->e_ehsize != sizeof(Elf_Ehdr)) {
|
604
|
+
set_errmsg("invalid elf header size: %u", ehdr->e_ehsize);
|
605
|
+
return PLTHOOK_INVALID_FILE_FORMAT;
|
606
|
+
}
|
607
|
+
if (ehdr->e_phentsize != sizeof(Elf_Phdr)) {
|
608
|
+
set_errmsg("invalid program header table entry size: %u", ehdr->e_phentsize);
|
609
|
+
return PLTHOOK_INVALID_FILE_FORMAT;
|
610
|
+
}
|
611
|
+
return 0;
|
386
612
|
}
|
387
613
|
|
388
614
|
int plthook_enum(plthook_t *plthook, unsigned int *pos, const char **name_out, void ***addr_out)
|
389
615
|
{
|
390
616
|
while (*pos < plthook->plt_cnt) {
|
391
617
|
const Elf_Plt_Rel *plt = plthook->plt + *pos;
|
392
|
-
if (ELF_R_TYPE(plt->r_info) ==
|
618
|
+
if (ELF_R_TYPE(plt->r_info) == plthook->r_type) {
|
393
619
|
size_t idx = ELF_R_SYM(plt->r_info);
|
394
620
|
|
395
|
-
if (idx >= plthook->dynsym_cnt) {
|
396
|
-
set_errmsg(".dynsym index %" SIZE_T_FMT " should be less than %" SIZE_T_FMT ".", idx, plthook->dynsym_cnt);
|
397
|
-
return PLTHOOK_INVALID_FILE_FORMAT;
|
398
|
-
}
|
399
621
|
idx = plthook->dynsym[idx].st_name;
|
400
622
|
if (idx + 1 > plthook->dynstr_size) {
|
401
623
|
set_errmsg("too big section header string table index: %" SIZE_T_FMT, idx);
|
402
624
|
return PLTHOOK_INVALID_FILE_FORMAT;
|
403
625
|
}
|
404
626
|
*name_out = plthook->dynstr + idx;
|
405
|
-
*addr_out = (void**)(plthook->
|
627
|
+
*addr_out = (void**)(plthook->plt_addr_base + plt->r_offset);
|
406
628
|
(*pos)++;
|
407
629
|
return 0;
|
408
630
|
}
|
@@ -428,10 +650,26 @@ int plthook_replace(plthook_t *plthook, const char *funcname, void *funcaddr, vo
|
|
428
650
|
while ((rv = plthook_enum(plthook, &pos, &name, &addr)) == 0) {
|
429
651
|
if (strncmp(name, funcname, funcnamelen) == 0) {
|
430
652
|
if (name[funcnamelen] == '\0' || name[funcnamelen] == '@') {
|
653
|
+
#ifdef SUPPORT_RELRO
|
654
|
+
void *maddr = NULL;
|
655
|
+
if (plthook->relro_start <= (char*)addr && (char*)addr < plthook->relro_end) {
|
656
|
+
maddr = (void*)((size_t)addr & ~(page_size - 1));
|
657
|
+
if (mprotect(maddr, page_size, PROT_READ | PROT_WRITE) != 0) {
|
658
|
+
set_errmsg("Could not change the process memory protection at %p: %s",
|
659
|
+
maddr, strerror(errno));
|
660
|
+
return PLTHOOK_INTERNAL_ERROR;
|
661
|
+
}
|
662
|
+
}
|
663
|
+
#endif
|
431
664
|
if (oldfunc) {
|
432
665
|
*oldfunc = *addr;
|
433
666
|
}
|
434
667
|
*addr = funcaddr;
|
668
|
+
#ifdef SUPPORT_RELRO
|
669
|
+
if (maddr != NULL) {
|
670
|
+
mprotect(maddr, page_size, PROT_READ);
|
671
|
+
}
|
672
|
+
#endif
|
435
673
|
return 0;
|
436
674
|
}
|
437
675
|
}
|
@@ -446,8 +684,6 @@ int plthook_replace(plthook_t *plthook, const char *funcname, void *funcaddr, vo
|
|
446
684
|
void plthook_close(plthook_t *plthook)
|
447
685
|
{
|
448
686
|
if (plthook != NULL) {
|
449
|
-
free(plthook->shdr);
|
450
|
-
free(plthook->shstrtab);
|
451
687
|
free(plthook);
|
452
688
|
}
|
453
689
|
}
|
@@ -457,77 +693,6 @@ const char *plthook_error(void)
|
|
457
693
|
return errmsg;
|
458
694
|
}
|
459
695
|
|
460
|
-
static int check_elf_header(const Elf_Ehdr *ehdr)
|
461
|
-
{
|
462
|
-
if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) {
|
463
|
-
set_errmsg("invalid file signature: 0x%02x,0x%02x,0x%02x,0x%02x",
|
464
|
-
ehdr->e_ident[0], ehdr->e_ident[1], ehdr->e_ident[2], ehdr->e_ident[3]);
|
465
|
-
return PLTHOOK_INVALID_FILE_FORMAT;
|
466
|
-
}
|
467
|
-
if (ehdr->e_ident[EI_CLASS] != ELF_CLASS) {
|
468
|
-
set_errmsg("invalid elf class: 0x%02x", ehdr->e_ident[EI_CLASS]);
|
469
|
-
return PLTHOOK_INVALID_FILE_FORMAT;
|
470
|
-
}
|
471
|
-
if (ehdr->e_ident[EI_DATA] != ELF_DATA) {
|
472
|
-
set_errmsg("invalid elf data: 0x%02x", ehdr->e_ident[EI_DATA]);
|
473
|
-
return PLTHOOK_INVALID_FILE_FORMAT;
|
474
|
-
}
|
475
|
-
if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) {
|
476
|
-
set_errmsg("invalid elf version: 0x%02x", ehdr->e_ident[EI_VERSION]);
|
477
|
-
return PLTHOOK_INVALID_FILE_FORMAT;
|
478
|
-
}
|
479
|
-
if (ehdr->e_ident[EI_OSABI] != ELF_OSABI) {
|
480
|
-
set_errmsg("invalid OS ABI: 0x%02x", ehdr->e_ident[EI_OSABI]);
|
481
|
-
return PLTHOOK_INVALID_FILE_FORMAT;
|
482
|
-
}
|
483
|
-
if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) {
|
484
|
-
set_errmsg("invalid file type: 0x%04x", ehdr->e_type);
|
485
|
-
return PLTHOOK_INVALID_FILE_FORMAT;
|
486
|
-
}
|
487
|
-
if (ehdr->e_machine != E_MACHINE) {
|
488
|
-
set_errmsg("invalid machine type: %u", ehdr->e_machine);
|
489
|
-
return PLTHOOK_INVALID_FILE_FORMAT;
|
490
|
-
}
|
491
|
-
if (ehdr->e_version != EV_CURRENT) {
|
492
|
-
set_errmsg("invalid object file version: %u", ehdr->e_version);
|
493
|
-
return PLTHOOK_INVALID_FILE_FORMAT;
|
494
|
-
}
|
495
|
-
if (ehdr->e_ehsize != sizeof(Elf_Ehdr)) {
|
496
|
-
set_errmsg("invalid elf header size: %u", ehdr->e_ehsize);
|
497
|
-
return PLTHOOK_INVALID_FILE_FORMAT;
|
498
|
-
}
|
499
|
-
if (ehdr->e_phentsize != sizeof(Elf_Phdr)) {
|
500
|
-
set_errmsg("invalid program header table entry size: %u", ehdr->e_phentsize);
|
501
|
-
return PLTHOOK_INVALID_FILE_FORMAT;
|
502
|
-
}
|
503
|
-
if (ehdr->e_shentsize != sizeof(Elf_Shdr)) {
|
504
|
-
set_errmsg("invalid section header table entry size: %u", ehdr->e_shentsize);
|
505
|
-
return PLTHOOK_INVALID_FILE_FORMAT;
|
506
|
-
}
|
507
|
-
return 0;
|
508
|
-
}
|
509
|
-
|
510
|
-
static int find_section(plthook_t *image, const char *name, const Elf_Shdr **out)
|
511
|
-
{
|
512
|
-
const Elf_Shdr *shdr = image->shdr;
|
513
|
-
const Elf_Shdr *shdr_end = shdr + image->shnum;
|
514
|
-
size_t namelen = strlen(name);
|
515
|
-
|
516
|
-
while (shdr < shdr_end) {
|
517
|
-
if (shdr->sh_name + namelen >= image->shstrtab_size) {
|
518
|
-
set_errmsg("too big section header string table index: %u", shdr->sh_name);
|
519
|
-
return PLTHOOK_INVALID_FILE_FORMAT;
|
520
|
-
}
|
521
|
-
if (strcmp(image->shstrtab + shdr->sh_name, name) == 0) {
|
522
|
-
*out = shdr;
|
523
|
-
return 0;
|
524
|
-
}
|
525
|
-
shdr++;
|
526
|
-
}
|
527
|
-
set_errmsg("failed to find the section header: %s", name);
|
528
|
-
return PLTHOOK_INVALID_FILE_FORMAT;
|
529
|
-
}
|
530
|
-
|
531
696
|
static void set_errmsg(const char *fmt, ...)
|
532
697
|
{
|
533
698
|
va_list ap;
|