]>
git.saurik.com Git - cycript.git/blob - Inject.cpp
95610d23466d425289c7acbd21baf676a55b9f3d
   1 /* Cycript - Optimizing JavaScript Compiler/Runtime 
   2  * Copyright (C) 2009-2014  Jay Freeman (saurik) 
   5 /* GNU Affero General Public License, Version 3 {{{ */ 
   7  * This program is free software: you can redistribute it and/or modify 
   8  * it under the terms of the GNU Affero General Public License as published by 
   9  * the Free Software Foundation, either version 3 of the License, or 
  10  * (at your option) any later version. 
  12  * This program is distributed in the hope that it will be useful, 
  13  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  15  * GNU Affero General Public License for more details. 
  17  * You should have received a copy of the GNU Affero General Public License 
  18  * along with this program.  If not, see <http://www.gnu.org/licenses/>. 
  27 #include "Exception.hpp" 
  28 #include "Pooling.hpp" 
  30 #if defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__)) 
  31 #include <sys/fcntl.h> 
  34 #include <mach-o/loader.h> 
  36 #define CS_OPS_PIDOFFSET 6 
  38 extern "C" int csops(pid_t pid
, unsigned int ops
, void *useraddr
, size_t usersize
); 
  39 extern "C" int proc_pidpath(int pid
, void *buffer
, uint32_t buffersize
); 
  42 int main(int argc
, char * const argv
[], char const * const envp
[]); 
  43 extern "C" char *MSmain0(int argc
, char *argv
[]); 
  45 static std::string 
LibraryFor(void *address
) { 
  47     _assert(dladdr(address
, &info
) != 0); 
  48     return info
.dli_fname
; 
  51 template <typename Type_
> 
  52 Type_ 
*shift(Type_ 
*data
, size_t size
) { 
  53     return reinterpret_cast<Type_ 
*>(reinterpret_cast<uint8_t *>(data
) + size
); 
  56 void InjectLibrary(int pid
, int argc
, const char *argv
[]) { 
  57     auto cynject(LibraryFor(reinterpret_cast<void *>(&main
))); 
  58     auto slash(cynject
.rfind('/')); 
  59     _assert(slash 
!= std::string::npos
); 
  60     cynject 
= cynject
.substr(0, slash
) + "/cynject"; 
  62     auto library(LibraryFor(reinterpret_cast<void *>(&MSmain0
))); 
  64 #if defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__)) 
  66     _assert(csops(pid
, CS_OPS_PIDOFFSET
, &offset
, sizeof(offset
)) != -1); 
  69     int writ(proc_pidpath(pid
, path
, sizeof(path
))); 
  72     auto fd(_syscall(open(path
, O_RDONLY
))); 
  74     auto page(getpagesize()); 
  76     auto map(_syscall(mmap(NULL
, size
, PROT_READ
, MAP_SHARED
, fd
, offset
))); 
  78     _syscall(close(fd
)); // XXX: _scope 
  80     auto header(reinterpret_cast<mach_header 
*>(map
)); 
  81     auto command(reinterpret_cast<load_command 
*>(header 
+ 1)); 
  83     switch (header
->magic
) { 
  85             command 
= shift(command
, sizeof(uint32_t)); 
  93     for (decltype(header
->ncmds
) i(0); i 
!= header
->ncmds
; ++i
) { 
  94         if (command
->cmd 
== LC_VERSION_MIN_IPHONEOS
) 
  96         command 
= shift(command
, command
->cmdsize
); 
  99     _syscall(munmap(map
, size
)); // XXX: _scope 
 101     auto length(library
.size()); 
 102     _assert(length 
>= 6); 
 105     _assert(library
.substr(length
) == ".dylib"); 
 106     library 
= library
.substr(0, length
); 
 107     library 
+= ios 
? "-sim" : "-sys"; 
 111     std::ostringstream inject
; 
 112     inject 
<< cynject 
<< " " << std::dec 
<< pid 
<< " " << library
; 
 113     for (decltype(argc
) i(0); i 
!= argc
; ++i
) 
 114         inject 
<< " " << argv
[i
]; 
 116     _assert(system(inject
.str().c_str()) == 0);