Safari and getaddrinfo interposing
Safari and getaddrinfo interposing
我写了一个小型动态库,用于插入对getaddrinfo和connect的调用。 我使用 Firefox 和 Safari 上的DYLD_INSERT_LIBRARIES插入此库来劫持 www.apple.com 请求并将它们发送到 www.microsoft.com。 该代码在 Firefox 上有效,但是当 Safari 调用我的插入函数时,它会忽略重定向。
我想知道是否有人深入了解为什么 Safari 忽略重定向,以及是否有办法,也许通过 addrinfo 标志,让 Safari 像 Firefox 一样运行。 我的代码清单如下。
// -*- mode: c++ -*-
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <dlfcn.h>
#include <dns_sd.h>
#include <cstdio>
#include <cstdlib>
#include <cstdarg>
#include <cstring>
#include <string>
typedef int (*connect_type) (int, struct sockaddr const*, socklen_t);
typedef int (*getaddrinfo_type)(
const char*, const char*, struct addrinfo const*, addrinfo**);
connect_type real_connect = 0;
getaddrinfo_type real_getaddrinfo = 0;
int
do_getaddrinfo_impl(const char* nodename, const char* servname,
struct addrinfo const* hints, struct addrinfo** ppai)
{
int result = real_getaddrinfo (nodename, servname, hints, ppai);
if(result != 0) {
fprintf(stderr, "! real_getaddrinfo error on %s: %sn", nodename, gai_strerror(result));
}
return result;
}
int
do_getaddrinfo(const char* nodename, const char* servname,
struct addrinfo const* hints, struct addrinfo** ppai)
{
if (0 == nodename) {
return do_getaddrinfo_impl(nodename, servname, hints, ppai);
}
if (hints->ai_family == AF_INET6) {
printf ("# do_getaddrinfo : IPv6 resolutionn");
return do_getaddrinfo_impl(nodename, servname, hints, ppai);
}
if ( hints->ai_flags & AI_PASSIVE
|| hints->ai_flags & AI_CANONNAME
|| hints->ai_flags & AI_NUMERICHOST
|| hints->ai_flags & AI_NUMERICSERV) {
printf ("# do_getaddrinfo : unsupported resolution flagsn");
return do_getaddrinfo_impl (nodename, servname, hints, ppai);
}
if ((hints->ai_flags & AI_V4MAPPED) && !(hints->ai_flags & AI_ALL)) {
printf ("# do_getaddrinfo : unsupported IPv6-mappingn");
return do_getaddrinfo_impl (nodename, servname, hints, ppai);
}
// redirect requests for www.apple.com to microsoft at 65.55.57.80 (0x41373950)
if(0 == strcmp(nodename, "www.apple.com")) {
addrinfo* pai = (addrinfo*)calloc (1, sizeof (addrinfo));
pai->ai_flags = hints->ai_flags;
pai->ai_family = AF_INET;
pai->ai_socktype = hints->ai_socktype;
pai->ai_protocol = IPPROTO_TCP;
pai->ai_addrlen = sizeof (sockaddr_in);
sockaddr* psa = reinterpret_cast< sockaddr* > (
calloc (1, sizeof (sockaddr)));
sockaddr_in& sain = reinterpret_cast< sockaddr_in& > (*psa);
#if !defined (POS_NO_SIN_LEN)
sain.sin_len = sizeof *psa;
#endif // POS_NO_SIN_LEN
sain.sin_family = AF_INET;
sain.sin_addr.s_addr = htonl(0x41373950);
pai->ai_addr = psa;
pai->ai_canonname = 0;
pai->ai_next = 0;
*ppai = pai;
return 0;
}
else {
return do_getaddrinfo_impl(nodename, servname, hints, ppai);
}
}
////////////////////////////////////////////////////////////////////////
extern "C" {
int
fake_getaddrinfo(const char* nodename, const char* servname,
struct addrinfo const* hints, struct addrinfo** ppai)
{
if (real_getaddrinfo == 0)
real_getaddrinfo = &getaddrinfo;
return do_getaddrinfo (nodename, servname, hints, ppai);
}
int
fake_connect (int s, sockaddr const* ptr, socklen_t len)
{
if (real_connect == 0)
real_connect = &connect;
return do_connect (s, ptr, len);
}
__attribute__((used)) static struct {
void const *a, *b;
} arr [] __attribute__ ((section ("__DATA, __interpose"))) = {
{ (void*)fake_connect, (void*)connect },
{ (void*)fake_getaddrinfo, (void*)getaddrinfo }
};
} // extern "C"
作为后续操作,我发现 Safari 正在 hints 参数中设置 AI_NUMERICHOST 标志,因此将该标志作为不受支持的分辨率标志进行测试导致我的重定向代码从未被调用。 我删除了AI_NUMERICHOST测试,并添加了以下位来解决问题。
if (hints->ai_flags & AI_NUMERICHOST) {
//
// Safari makes name resolution requests using AI_NUMERICHOST
//
in_addr_t addr = inet_addr (nodename);
if (addr != INADDR_NONE)
return do_getaddrinfo_impl (nodename, servname, hints, ppai);
}
希望对别人有帮助。
相关文章:
- Cpp-Tuple使用带有变量的get
- 通过 get-Method 访问变量在类外不起作用
- 为什么无论你输入什么,这"while(cin.get(str,3))"只运行一次?
- Boost.Asio/OpenSSL HTTPS GET certificate trouble
- C++中是否有任何函数等同于python中字典的get函数?
- 使用istringstearm和get行缓慢读取文件
- 如何将 c++ get 函数代码转换为 opencv 算法中使用的 python
- 使用 cin.get() 初始化字符数组
- std::variant<>::get() 不能使用 Apple LLVM 10.0 编译
- 编写 cin.get() 以接收字符数组时出现问题
- 作用域枚举和标准::get
- Visual Studio 2017 中的 cpprestapi 问题找不到 POST/GET 常量
- 在 C++/C 中使用 CURL 发出带有数据文件的 GET HTTP 请求
- 使用"push_back"作为带有"get"函数C++的向量
- 使用 cin.get 读取字符数组
- 如何使用 fstream 的 .get 字符串?
- std::get like (partial) template specialization
- 从 unique_ptr::get 发送指针作为指针引用进入函数
- addr2line get 行号始终返回 0
- unique_ptr<T>::get() 返回的指针在原始unique_ptr被销毁后不是 nullptr