Le 3 sept. 08 à 11:48, Luke Daley a écrit :
Hi,
This was the select and svn discussion, but we have narrowed the problem down to syscall() on 64 bit Leopard so I am starting a new thread.
`man syscall` tells us that you need to use __syscall() on 64 bit architectures. The problem with that though is that __syscall() is in libSystem, but is not exported. Jean-Daniel Dupas then contributed this code to get to __syscall()…
#include <libc.h>
#include <mach-o/nlist.h>
typedef int (*__syscall_t)(quad_t number, ...);
int main(int argc, const char * argv[]) {
struct nlist nl[1];
bzero(&nl, sizeof(struct nlist) * 2);
nl[0].n_un.n_name = (char *)"___syscall";
if (nlist("/usr/lib/libSystem.dylib", nl) < 0 || nl[0].n_type == N_UNDF) {
fprintf(stderr, "nlist(%s, %s) failed\n",
"/usr/lib/libSystem.dylib",
nl[0].n_un.n_name);
return -1;
}
__syscall_t fcn = (__syscall_t)nl[0].n_value;
return 0;
}
Except that gives "error: ‘union <anonymous>’ has no member named ‘n_name’".
Looking at mach-o/nlist.h…
struct nlist {
union {
#ifndef __LP64__
char *n_name; /* for use when in-core */
#endif
int32_t n_strx; /* index into the string table */
} n_un;
uint8_t n_type; /* type flag, see below */
uint8_t n_sect; /* section number or NO_SECT */
int16_t n_desc; /* see <mach-o/stab.h> */
uint32_t n_value; /* value of this symbol (or stab offset) */
};
That looks to me line n_name isn't there on 64 bit architectures.
Can I get at this any other way?
--
I just have a question. Why do you need syscall ? How are you currently performing your interposition ?
I think using the following technic, you don't have to use syscall at all. Create a dylib that contains your interposition code, and then use the DYLD_INSERT_LIBRARIES env to load your dylib into the target application.
/*
* interpose.c
*
* static
* int
* my_open(const char* path, int flags, mode_t mode)
* {
* int value;
* // do stuff before open (including changing the arguments)
* value = open(path, flags, mode);
* // do stuff after open (including changing the return value(s))
* return value;
* }
* DYLD_INTERPOSE(my_open, open)
*/
#define DYLD_INTERPOSE(_replacment,_replacee) \
__attribute__((used)) static struct{ const void* replacment; const void* replacee; } _interpose_##_replacee \
__attribute__ ((section ("__DATA,__interpose"))) = { (const void*)(unsigned long)&_replacment, (const void*)(unsigned long)&_replacee };
int my_open(const char *, int, mode_t);
int my_close(int);
DYLD_INTERPOSE(my_open, open);
DYLD_INTERPOSE(my_close, close);
int my_open(const char *path, int flags, mode_t mode) {
int ret = open(path, flags, mode);
printf("--> %d = open(%s, %x, %x)\n", ret, path, flags, mode);
return ret;
}
int my_close(int d) {
int ret = close(d);
printf("--> %d = close(%d)\n", ret, d);
return ret;
}