├── .gitignore
├── ARM.hpp
├── Baton.hpp
├── Bootstrap.cpp
├── Buffer.hpp
├── Common.hpp
├── Cydia.hpp
├── Cydia.mm
├── CydiaSubstrate.h
├── DarwinFindSymbol.cpp
├── DarwinInjector.cpp
├── DarwinLauncher.cpp
├── DarwinLoader.cpp
├── DarwinThreadInternal.hpp
├── Debug.cpp
├── Debug.hpp
├── Environment.cpp
├── Environment.hpp
├── Hooker.cpp
├── Info.plist
├── LaunchDaemons.hpp
├── LaunchDaemons.mm
├── Log.hpp
├── MachInterface.sh
├── MachMemory.cpp
├── MachMessage.cpp
├── MachMessage.hpp
├── MachProtect.defs
├── MobileSafety.jpg
├── MobileSafety.mm
├── MobileSafety.png
├── ObjectiveC.cpp
├── PosixMemory.cpp
├── TestSuperCall.mm
├── Trampoline.hpp
├── Trampoline.t.cpp
├── control
├── control.arm
├── control.i386
├── control.sh
├── cycc
├── cynject.cpp
├── darwin.mk
├── extra
├── CoreFoundation
│ ├── CFBundlePriv.h
│ ├── CFLogUtilities.h
│ └── CFPriv.h
└── machine
│ └── exec.h
├── extrainst_.mm
├── hde64c
├── LICENSE
├── NEWS
├── THANKS
├── doc
│ ├── en
│ │ └── manual.txt
│ └── ru
│ │ └── manual.txt
├── examples
│ └── example.c
├── include
│ └── hde64.h
└── src
│ ├── hde64.c
│ └── table64.h
├── include
├── System
│ └── machine
│ │ └── cpu_capabilities.h
├── machine
│ └── cpu_capabilities.h
├── posix_sched.h
├── pthread_internals.h
├── pthread_machdep.h
├── pthread_spinlock.h
└── pthread_spis.h
├── ldid.sh
├── package.sh
├── postrm.mm
├── safe.sh
├── task_for_pid.xml
├── trampoline.sh
├── version.sh
└── x86.hpp
/.gitignore:
--------------------------------------------------------------------------------
1 | *.o
2 | *.dylib
3 | *.deb
4 | *.t.hpp
5 | MachProtect.h
6 | MachProtect.c
7 | package.*
8 | extrainst_
9 | postrm
10 | cynject
11 | TestSuperCall
12 |
--------------------------------------------------------------------------------
/ARM.hpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #ifndef SUBSTRATE_ARM_HPP
23 | #define SUBSTRATE_ARM_HPP
24 |
25 | enum A$r {
26 | A$r0, A$r1, A$r2, A$r3,
27 | A$r4, A$r5, A$r6, A$r7,
28 | A$r8, A$r9, A$r10, A$r11,
29 | A$r12, A$r13, A$r14, A$r15,
30 | A$sp = A$r13,
31 | A$lr = A$r14,
32 | A$pc = A$r15
33 | };
34 |
35 | enum A$c {
36 | A$eq, A$ne, A$cs, A$cc,
37 | A$mi, A$pl, A$vs, A$vc,
38 | A$hi, A$ls, A$ge, A$lt,
39 | A$gt, A$le, A$al,
40 | A$hs = A$cs,
41 | A$lo = A$cc
42 | };
43 |
44 | #define A$mrs_rm_cpsr(rd) /* mrs rd, cpsr */ \
45 | (0xe10f0000 | ((rd) << 12))
46 | #define A$msr_cpsr_f_rm(rm) /* msr cpsr_f, rm */ \
47 | (0xe128f000 | (rm))
48 | #define A$ldr_rd_$rn_im$(rd, rn, im) /* ldr rd, [rn, #im] */ \
49 | (0xe5100000 | ((im) < 0 ? 0 : 1 << 23) | ((rn) << 16) | ((rd) << 12) | abs(im))
50 | #define A$str_rd_$rn_im$(rd, rn, im) /* sr rd, [rn, #im] */ \
51 | (0xe5000000 | ((im) < 0 ? 0 : 1 << 23) | ((rn) << 16) | ((rd) << 12) | abs(im))
52 | #define A$sub_rd_rn_$im(rd, rn, im) /* sub, rd, rn, #im */ \
53 | (0xe2400000 | ((rn) << 16) | ((rd) << 12) | (im & 0xff))
54 | #define A$blx_rm(rm) /* blx rm */ \
55 | (0xe12fff30 | (rm))
56 | #define A$mov_rd_rm(rd, rm) /* mov rd, rm */ \
57 | (0xe1a00000 | ((rd) << 12) | (rm))
58 | #define A$ldmia_sp$_$rs$(rs) /* ldmia sp!, {rs} */ \
59 | (0xe8b00000 | (A$sp << 16) | (rs))
60 | #define A$stmdb_sp$_$rs$(rs) /* stmdb sp!, {rs} */ \
61 | (0xe9200000 | (A$sp << 16) | (rs))
62 | #define A$stmia_sp$_$r0$ 0xe8ad0001 /* stmia sp!, {r0} */
63 | #define A$bx_r0 0xe12fff10 /* bx r0 */
64 |
65 | #endif//SUBSTRATE_ARM_HPP
66 |
--------------------------------------------------------------------------------
/Baton.hpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #ifndef SUBSTRATE_BATOM_HPP
23 | #define SUBSTRATE_BATOM_HPP
24 |
25 | #include
26 | #include
27 | #include
28 |
29 | struct Baton {
30 | void (*__pthread_set_self)(pthread_t);
31 |
32 | int (*pthread_create)(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *);
33 | int (*pthread_join)(pthread_t, void **);
34 |
35 | mach_port_t (*mach_thread_self)();
36 | kern_return_t (*thread_terminate)(thread_act_t);
37 |
38 | char *(*dlerror)();
39 | void *(*dlsym)(void *, const char *);
40 |
41 | char library[];
42 | };
43 |
44 | #endif//SUBSTRATE_BATOM_HPP
45 |
--------------------------------------------------------------------------------
/Bootstrap.cpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #include "CydiaSubstrate.h"
23 |
24 | #include
25 |
26 | MSInitialize {
27 | if (getenv("MSExitZero") != NULL) {
28 | // skeels / planetbeing / rpetrich <- reporting SMS crash
29 | if (dlopen("/System/Library/PrivateFrameworks/Search.framework/AppIndexer", RTLD_LAZY | RTLD_NOLOAD) != NULL)
30 | _exit(EXIT_FAILURE);
31 |
32 | _exit(EXIT_SUCCESS);
33 | }
34 |
35 | // Skype
36 | if (dlopen("/System/Library/Frameworks/Security.framework/Security", RTLD_LAZY | RTLD_NOLOAD) == NULL)
37 | return;
38 |
39 | // Maps
40 | dlopen("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation", RTLD_LAZY | RTLD_GLOBAL);
41 |
42 | dlopen("/Library/Frameworks/CydiaSubstrate.framework/Libraries/SubstrateLoader.dylib", RTLD_LAZY | RTLD_GLOBAL);
43 | }
44 |
--------------------------------------------------------------------------------
/Buffer.hpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #ifndef SUBSTRATE_BUFFER_HPP
23 | #define SUBSTRATE_BUFFER_HPP
24 |
25 | #include
26 |
27 | template
28 | _disused static _finline void MSWrite(uint8_t *&buffer, Type_ value) {
29 | *reinterpret_cast(buffer) = value;
30 | buffer += sizeof(Type_);
31 | }
32 |
33 | _disused static _finline void MSWrite(uint8_t *&buffer, uint8_t *data, size_t size) {
34 | memcpy(buffer, data, size);
35 | buffer += size;
36 | }
37 |
38 | #endif//SUBSTRATE_BUFFER_HPP
39 |
--------------------------------------------------------------------------------
/Common.hpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #ifndef SUBSTRATE_COMMON_HPP
23 | #define SUBSTRATE_COMMON_HPP
24 |
25 | #include
26 | #include "Log.hpp"
27 |
28 | #define _syscall(expr) ({ \
29 | __typeof__(expr) _value; \
30 | for(;;) if ((long) (_value = (expr)) != -1 || errno != EINTR) \
31 | break; \
32 | _value; \
33 | })
34 |
35 | #define _trace() do { \
36 | MSLog(MSLogLevelError, "%s(%d): _trace()", __FILE__, __LINE__); \
37 | } while (false)
38 |
39 | #endif//SUBSTRATE_COMMON_HPP
40 |
--------------------------------------------------------------------------------
/Cydia.hpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #ifndef SUBSTRATE_CYDIA_HPP
23 | #define SUBSTRATE_CYDIA_HPP
24 |
25 | void FinishCydia(const char *finish);
26 |
27 | enum ForkBugStatus {
28 | ForkBugUnknown,
29 | ForkBugMissing,
30 | ForkBugPresent,
31 | };
32 |
33 | ForkBugStatus DetectForkBug();
34 |
35 | #endif//SUBSTRATE_CYDIA_HPP
36 |
--------------------------------------------------------------------------------
/Cydia.mm:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #include
23 |
24 | #include
25 | #include
26 |
27 | #include
28 |
29 | #include "Common.hpp"
30 | #include "Cydia.hpp"
31 |
32 | void FinishCydia(const char *finish) {
33 | if (finish == NULL)
34 | return;
35 |
36 | const char *cydia(getenv("CYDIA"));
37 | if (cydia == NULL)
38 | return;
39 |
40 |
41 | // XXX: I think I'd like to rewrite this code using C++
42 | int fd([[[[NSString stringWithUTF8String:cydia] componentsSeparatedByString:@" "] objectAtIndex:0] intValue]);
43 |
44 | FILE *fout(fdopen(fd, "w"));
45 | fprintf(fout, "finish:%s\n", finish);
46 | fclose(fout);
47 | }
48 |
49 | ForkBugStatus DetectForkBug() {
50 | mach_port_t self(mach_task_self());
51 | int page(getpagesize());
52 |
53 | volatile uint8_t *data(reinterpret_cast(&fopen));
54 | uintptr_t base(reinterpret_cast(data) / page * page);
55 |
56 | vm_protect(self, base, page, FALSE, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY);
57 | data[0] = data[0];
58 | vm_protect(self, base, page, FALSE, VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
59 |
60 | pid_t pid(fork());
61 | if (pid == 0) {
62 | fopen("/tmp/fork", "rb");
63 | _exit(EXIT_SUCCESS);
64 | }
65 |
66 | int status;
67 | if (_syscall(waitpid(pid, &status, 0) == -1)) {
68 | fprintf(stderr, "waitpid() -> %d\n", errno);
69 | return ForkBugUnknown;
70 | }
71 |
72 | if (WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS)
73 | return ForkBugMissing;
74 | else
75 | // XXX: consider checking for a killed status, and returning ForBugUnknown if not
76 | return ForkBugPresent;
77 | }
78 |
--------------------------------------------------------------------------------
/DarwinFindSymbol.cpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #include
23 | #include
24 |
25 | #include
26 | #include
27 | #include
28 |
29 | extern "C" {
30 | #include
31 | }
32 |
33 | #define BSD_KERNEL_PRIVATE
34 | #include
35 | #include
36 |
37 | #include
38 | #include
39 |
40 | #include "CydiaSubstrate.h"
41 |
42 | #define _trace() do { \
43 | MSLog(MSLogLevelNotice, "_trace(%u)", __LINE__); \
44 | } while (false)
45 |
46 | struct MSSymbolData {
47 | const char *name_;
48 | uint8_t type_;
49 | uint8_t sect_;
50 | int16_t desc_;
51 | uintptr_t value_;
52 | };
53 |
54 | #ifdef __LP64__
55 | typedef struct mach_header_64 mach_header_xx;
56 | typedef struct nlist_64 nlist_xx;
57 | typedef struct segment_command_64 segment_command_xx;
58 |
59 | static const uint32_t LC_SEGMENT_XX = LC_SEGMENT_64;
60 | static const uint32_t MH_MAGIC_XX = MH_MAGIC_64;
61 | #else
62 | typedef struct mach_header mach_header_xx;
63 | typedef struct nlist nlist_xx;
64 | typedef struct segment_command segment_command_xx;
65 |
66 | static const uint32_t LC_SEGMENT_XX = LC_SEGMENT;
67 | static const uint32_t MH_MAGIC_XX = MH_MAGIC;
68 | #endif
69 |
70 | static ssize_t MSMachONameList_(const void *stuff, struct MSSymbolData *list, size_t nreq) {
71 | // XXX: ok, this is just pathetic; API fail much?
72 | size_t slide(0);
73 | for (uint32_t image(0), images(_dyld_image_count()); image != images; ++image)
74 | if (_dyld_get_image_header(image) == stuff) {
75 | slide = _dyld_get_image_vmaddr_slide(image);
76 | goto fat;
77 | }
78 |
79 | return -1;
80 |
81 | fat:
82 | const uint8_t *base(reinterpret_cast(stuff));
83 | const struct exec *buf(reinterpret_cast(base));
84 |
85 | if (OSSwapBigToHostInt32(buf->a_magic) == FAT_MAGIC) {
86 | struct host_basic_info hbi; {
87 | host_t host(mach_host_self());
88 | mach_msg_type_number_t count(HOST_BASIC_INFO_COUNT);
89 | if (host_info(host, HOST_BASIC_INFO, reinterpret_cast(&hbi), &count) != KERN_SUCCESS)
90 | return -1;
91 | mach_port_deallocate(mach_task_self(), host);
92 | }
93 |
94 | const struct fat_header *fh(reinterpret_cast(base));
95 | uint32_t nfat_arch(OSSwapBigToHostInt32(fh->nfat_arch));
96 | const struct fat_arch *fat_archs(reinterpret_cast(fh + 1));
97 |
98 | for (uint32_t i(0); i != nfat_arch; ++i)
99 | if (static_cast(OSSwapBigToHostInt32(fat_archs[i].cputype)) == hbi.cpu_type) {
100 | buf = reinterpret_cast(base + OSSwapBigToHostInt32(fat_archs[i].offset));
101 | goto thin;
102 | }
103 |
104 | return -1;
105 | }
106 |
107 | thin:
108 | const nlist_xx *symbols;
109 | const char *strings;
110 | size_t n;
111 |
112 | // XXX: this check looks really scary when it fails
113 | if (buf->a_magic == MH_MAGIC_XX) {
114 | const mach_header_xx *mh(reinterpret_cast(base));
115 | const struct load_command *load_commands(reinterpret_cast(mh + 1));
116 |
117 | const struct symtab_command *stp(NULL);
118 | const struct load_command *lcp;
119 |
120 | /* forlc (command, mh, LC_SYMTAB, struct symtab_command) {
121 | stp = command;
122 | goto found;
123 | } */
124 |
125 | lcp = load_commands;
126 | for (uint32_t i(0); i != mh->ncmds; ++i) {
127 | if (
128 | lcp->cmdsize % sizeof(long) != 0 || lcp->cmdsize <= 0 ||
129 | reinterpret_cast(lcp) + lcp->cmdsize > reinterpret_cast(load_commands) + mh->sizeofcmds
130 | )
131 | return -1;
132 |
133 | if (lcp->cmd == LC_SYMTAB) {
134 | if (lcp->cmdsize != sizeof(struct symtab_command))
135 | return -1;
136 | stp = reinterpret_cast(lcp);
137 | goto found;
138 | }
139 |
140 | lcp = reinterpret_cast(reinterpret_cast(lcp) + lcp->cmdsize);
141 | }
142 |
143 | return -1;
144 |
145 | found:
146 | n = stp->nsyms;
147 |
148 | symbols = NULL;
149 | strings = NULL;
150 |
151 | /* forlc (command, mh, LC_SEGMENT_XX, segment_command_xx) {
152 | stp = command;
153 | goto found;
154 | } */
155 |
156 | lcp = load_commands;
157 | for (uint32_t i(0); i != mh->ncmds; ++i) {
158 | if (
159 | lcp->cmdsize % sizeof(long) != 0 || lcp->cmdsize <= 0 ||
160 | reinterpret_cast(lcp) + lcp->cmdsize > reinterpret_cast(load_commands) + mh->sizeofcmds
161 | )
162 | return -1;
163 |
164 | if (lcp->cmd == LC_SEGMENT_XX) {
165 | if (lcp->cmdsize < sizeof(segment_command_xx))
166 | return -1;
167 | const segment_command_xx *segment(reinterpret_cast(lcp));
168 | if (stp->symoff >= segment->fileoff && stp->symoff < segment->fileoff + segment->filesize)
169 | symbols = reinterpret_cast(stp->symoff - segment->fileoff + segment->vmaddr + slide);
170 | if (stp->stroff >= segment->fileoff && stp->stroff < segment->fileoff + segment->filesize)
171 | strings = reinterpret_cast(stp->stroff - segment->fileoff + segment->vmaddr + slide);
172 | }
173 |
174 | lcp = reinterpret_cast(reinterpret_cast(lcp) + lcp->cmdsize);
175 | }
176 |
177 | if (symbols == NULL || strings == NULL)
178 | return -1;
179 | // XXX: detect a.out somehow?
180 | } else if (false) {
181 | /* XXX: is this right anymore?!? */
182 | symbols = reinterpret_cast(base + N_SYMOFF(*buf));
183 | strings = reinterpret_cast(reinterpret_cast(symbols) + buf->a_syms);
184 | n = buf->a_syms / sizeof(nlist_xx);
185 | } else return -1;
186 |
187 | size_t result(nreq);
188 |
189 | for (size_t m(0); m != n; ++m) {
190 | const nlist_xx *q(&symbols[m]);
191 | if (q->n_un.n_strx == 0 || (q->n_type & N_STAB) != 0)
192 | continue;
193 |
194 | const char *nambuf(strings + q->n_un.n_strx);
195 | //fprintf(stderr, " == %s\n", nambuf);
196 |
197 | for (size_t item(0); item != nreq; ++item) {
198 | struct MSSymbolData *p(list + item);
199 | if (p->name_ == NULL || strcmp(p->name_, nambuf) != 0)
200 | continue;
201 |
202 | p->name_ = NULL;
203 |
204 | p->value_ = q->n_value;
205 | if (p->value_ != 0)
206 | p->value_ += slide;
207 |
208 | p->type_ = q->n_type;
209 | p->desc_ = q->n_desc;
210 | p->sect_ = q->n_sect;
211 |
212 | if (--result == 0)
213 | return 0;
214 | break;
215 | }
216 | }
217 |
218 | return result;
219 | }
220 |
221 | _extern MSImageRef MSGetImageByName(const char *file) {
222 | for (uint32_t image(0), images(_dyld_image_count()); image != images; ++image)
223 | if (strcmp(_dyld_get_image_name(image), file) == 0)
224 | return _dyld_get_image_header(image);
225 | return NULL;
226 | }
227 |
228 | static void MSFindSymbols(MSImageRef image, size_t count, const char *names[], void *values[]) {
229 | MSSymbolData items[count];
230 |
231 | for (size_t index(0); index != count; ++index) {
232 | MSSymbolData &item(items[index]);
233 |
234 | item.name_ = names[index];
235 | item.type_ = 0;
236 | item.sect_ = 0;
237 | item.desc_ = 0;
238 | item.value_ = 0;
239 | }
240 |
241 | if (image != NULL)
242 | MSMachONameList_(image, items, count);
243 | else {
244 | size_t remain(count);
245 |
246 | for (uint32_t image(0), images(_dyld_image_count()); image != images; ++image) {
247 | //fprintf(stderr, ":: %s\n", _dyld_get_image_name(image));
248 |
249 | ssize_t result(MSMachONameList_(_dyld_get_image_header(image), items, count));
250 | if (result == -1)
251 | continue;
252 |
253 | // XXX: maybe avoid this happening at all? a flag to NSMachONameList_?
254 | for (size_t index(0); index != count; ++index) {
255 | MSSymbolData &item(items[index]);
256 | if (item.name_ == NULL && item.value_ == 0) {
257 | ++result;
258 | item.name_ = names[index];
259 | }
260 | }
261 |
262 | remain -= count - result;
263 | if (remain == 0)
264 | break;
265 | }
266 | }
267 |
268 | for (size_t index(0); index != count; ++index) {
269 | MSSymbolData &item(items[index]);
270 | uintptr_t value(item.value_);
271 | #ifdef __arm__
272 | if ((item.desc_ & N_ARM_THUMB_DEF) != 0)
273 | value |= 0x00000001;
274 | #endif
275 | values[index] = reinterpret_cast(value);
276 | }
277 | }
278 |
279 | _extern void *MSFindSymbol(MSImageRef image, const char *name) {
280 | void *value;
281 | MSFindSymbols(image, 1, &name, &value);
282 | return value;
283 | }
284 |
285 | #ifdef __arm__
286 | MSHook(int, nlist, const char *file, struct nlist *names) {
287 | const void *image(MSGetImageByName(file));
288 | if (image == NULL)
289 | return (*_nlist)(file, names);
290 |
291 | size_t count(0);
292 | for (struct nlist *list(names); list->n_un.n_name != NULL; ++list)
293 | ++count;
294 |
295 | MSSymbolData items[count];
296 |
297 | for (size_t index(0); index != count; ++index) {
298 | MSSymbolData &item(items[index]);
299 | struct nlist &name(names[index]);
300 |
301 | item.name_ = name.n_un.n_name;
302 | item.type_ = 0;
303 | item.sect_ = 0;
304 | item.desc_ = 0;
305 | item.value_ = 0;
306 | }
307 |
308 | int result(MSMachONameList_(image, items, count));
309 |
310 | for (size_t index(0); index != count; ++index) {
311 | MSSymbolData &item(items[index]);
312 | struct nlist &name(names[index]);
313 |
314 | name.n_type = item.type_;
315 | name.n_sect = item.sect_;
316 | name.n_desc = item.desc_;
317 | name.n_value = item.value_;
318 | }
319 |
320 | return result;
321 | }
322 |
323 | MSInitialize {
324 | MSHookFunction(&nlist, MSHake(nlist));
325 | }
326 | #endif
327 |
--------------------------------------------------------------------------------
/DarwinInjector.cpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #include
23 | #include
24 |
25 | #include
26 |
27 | #include
28 | #include
29 |
30 | #include "CydiaSubstrate.h"
31 |
32 | #include "Log.hpp"
33 |
34 | #include "Baton.hpp"
35 | #include "Trampoline.t.hpp"
36 |
37 | extern "C" void __pthread_set_self(pthread_t);
38 |
39 | #define _krncall(expr) \
40 | do { \
41 | kern_return_t _krnstatus((expr)); \
42 | if (_krnstatus != KERN_SUCCESS) { \
43 | MSLog(MSLogLevelError, "MS:Error: _krncall(%s)", #expr); \
44 | return false; \
45 | } \
46 | } while (false)
47 |
48 | _extern bool MSHookProcess(pid_t pid, const char *library) {
49 | if (library[0] != '/') {
50 | MSLog(MSLogLevelError, "MSError: require absolute path to %s", library);
51 | return false;
52 | }
53 |
54 | static const size_t Stack_(8 * 1024);
55 | size_t length(strlen(library) + 1), depth(sizeof(Baton) + length);
56 | depth = (depth + sizeof(uintptr_t) + 1) / sizeof(uintptr_t) * sizeof(uintptr_t);
57 |
58 | uint8_t local[depth];
59 | Baton *baton(reinterpret_cast(local));
60 |
61 |
62 | // the dyld shared cache is only shuffled once per boot, allowing us to assume no ASLR
63 | // however, it is important that we restrict ourselves to those in cached libraries
64 | // XXX: it would be preferable to do this in a cross-architecture way, remotely
65 |
66 | baton->__pthread_set_self = &__pthread_set_self;
67 |
68 | baton->pthread_create = &pthread_create;
69 | baton->pthread_join = &pthread_join;
70 |
71 | baton->mach_thread_self = &mach_thread_self;
72 | baton->thread_terminate = &thread_terminate;
73 |
74 | baton->dlerror = &dlerror;
75 | baton->dlsym = &dlsym;
76 |
77 |
78 | memcpy(baton->library, library, length);
79 |
80 | vm_size_t size(depth + Stack_);
81 |
82 | mach_port_t self(mach_task_self()), task;
83 | _krncall(task_for_pid(self, pid, &task));
84 |
85 | vm_address_t stack;
86 | _krncall(vm_allocate(task, &stack, size, true));
87 | vm_address_t data(stack + Stack_);
88 |
89 | _krncall(vm_write(task, data, reinterpret_cast(baton), depth));
90 |
91 | thread_act_t thread;
92 | _krncall(thread_create(task, &thread));
93 |
94 |
95 | // XXX: look into using thread_get_state(THREAD_STATE_FLAVOR_LIST) to look up flavor
96 |
97 | thread_state_flavor_t flavor;
98 | mach_msg_type_number_t count;
99 | size_t push;
100 |
101 | Trampoline *trampoline;
102 |
103 | #if defined(__arm__)
104 | trampoline = &Trampoline_armv6_;
105 | arm_thread_state_t state;
106 | flavor = ARM_THREAD_STATE;
107 | count = ARM_THREAD_STATE_COUNT;
108 | push = 0;
109 | #elif defined(__i386__)
110 | trampoline = &Trampoline_i386_;
111 | i386_thread_state_t state;
112 | flavor = i386_THREAD_STATE;
113 | count = i386_THREAD_STATE_COUNT;
114 | push = 5;
115 | #elif defined(__x86_64__)
116 | trampoline = &Trampoline_x86_64_;
117 | x86_thread_state64_t state;
118 | flavor = x86_THREAD_STATE64;
119 | count = x86_THREAD_STATE64_COUNT;
120 | push = 2;
121 | #else
122 | #error XXX: implement
123 | #endif
124 |
125 |
126 | vm_address_t code;
127 | _krncall(vm_allocate(task, &code, trampoline->size_, true));
128 | _krncall(vm_write(task, code, reinterpret_cast(trampoline->data_), trampoline->size_));
129 | _krncall(vm_protect(task, code, trampoline->size_, false, VM_PROT_READ | VM_PROT_EXECUTE));
130 |
131 | uint32_t frame[push];
132 | if (sizeof(frame) != 0)
133 | memset(frame, 0, sizeof(frame));
134 | memset(&state, 0, sizeof(state));
135 |
136 | mach_msg_type_number_t read(count);
137 | _krncall(thread_get_state(thread, flavor, reinterpret_cast(&state), &read));
138 |
139 | if (read != count) {
140 | MSLog(MSLogLevelError, "MSError: thread_get_state(%d) == %d", count, read);
141 | return false;
142 | }
143 |
144 |
145 | // this code is very similar to that found in Libc/pthread's _pthread_setup
146 |
147 | #if defined(__arm__)
148 | state.__r[0] = data;
149 | state.__sp = stack + Stack_;
150 | state.__pc = code + trampoline->entry_;
151 |
152 |
153 | // ARM has two execution states: ARM (32-bit) and Thumb (16/32-bit), using different instruction sets
154 | // for addressing, we tell using the least significant bit: off-aligned addresses are assumed to be Thumb
155 | // however, despite the CPU interpreting this bit during branches, it stores this information in CPSR
156 |
157 | if ((state.__pc & 0x1) != 0) {
158 | state.__pc &= ~0x1;
159 | state.__cpsr |= 0x20;
160 | }
161 | #elif defined(__i386__)
162 | frame[1] = data;
163 |
164 | state.__eip = code + trampoline->entry_;
165 | state.__esp = stack + Stack_ - sizeof(frame);
166 | #elif defined(__x86_64__)
167 | // XXX: I do not remember why this is here
168 | frame[0] = 0xdeadbeef;
169 |
170 | state.__rdi = data;
171 | state.__rip = code + trampoline->entry_;
172 | state.__rsp = stack + Stack_ - sizeof(frame);
173 | #else
174 | #error XXX: implement
175 | #endif
176 |
177 |
178 | if (sizeof(frame) != 0)
179 | _krncall(vm_write(task, stack + Stack_ - sizeof(frame), reinterpret_cast(frame), sizeof(frame)));
180 |
181 | _krncall(thread_set_state(thread, flavor, reinterpret_cast(&state), count));
182 | _krncall(thread_resume(thread));
183 |
184 |
185 | // XXX: I feel like there must be a way to get an event when the thread dies, rather than poll
186 | // XXX: all we now know is that the thread finished, but what we really care about is whether it worked
187 |
188 | do loop: switch (kern_return_t status = thread_get_state(thread, flavor, reinterpret_cast(&state), &(read = count))) {
189 | case KERN_SUCCESS:
190 | usleep(10000);
191 | goto loop;
192 |
193 | case KERN_TERMINATED:
194 | case MACH_SEND_INVALID_DEST:
195 | break;
196 |
197 | default:
198 | MSLog(MSLogLevelError, "MSError: thread_get_state() == %d", status);
199 | return false;
200 | } while (false);
201 |
202 |
203 | _krncall(mach_port_deallocate(self, thread));
204 |
205 | _krncall(vm_deallocate(task, code, trampoline->size_));
206 | _krncall(vm_deallocate(task, stack, size));
207 |
208 | _krncall(mach_port_deallocate(self, task));
209 |
210 | return true;
211 | }
212 |
--------------------------------------------------------------------------------
/DarwinLauncher.cpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #include "CydiaSubstrate.h"
23 |
24 | #include "Log.hpp"
25 |
26 | #include
27 |
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 |
35 | #include
36 |
37 | #include
38 |
39 | #include "Common.hpp"
40 | #include "Environment.hpp"
41 |
42 | #include
43 | #define environ (*_NSGetEnviron())
44 |
45 | MSHook(int, posix_spawn, pid_t *pid, const char *path, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t *attrp, char * const argv[], char * const envp[]) {
46 | // quit is a goto target that is used below to exit this function without manipulating envp
47 |
48 | if (false) quit:
49 | return _posix_spawn(pid, path, file_actions, attrp, argv, envp);
50 |
51 |
52 | // safe is a goto target that is used below to indicate that Substrate should be removed from envp
53 |
54 | bool safe(false);
55 | if (false) safe: {
56 | safe = true;
57 | goto scan;
58 | }
59 |
60 |
61 | // we use these arguments below, so we need to fix them or fail early
62 |
63 | if (path == NULL)
64 | goto quit;
65 | if (envp == NULL)
66 | envp = environ;
67 |
68 |
69 | // it is possible we are still installed in the kernel, even though substrate was removed
70 | // in this situation, it is safest if we goto safe, not quit, to remove DYLD_INSERT_LIBRARIES
71 |
72 | if (_syscall(access(SubstrateLibrary_, R_OK | X_OK)) == -1)
73 | goto safe;
74 |
75 |
76 | // if a process wants to turn off Substrate for its children, it needs to communicate this to us
77 | // a process can also indicate "I'm good, just do it", bypassing the later (expensive) safety checks
78 |
79 | for (char * const *env(envp); *env != NULL; ++env)
80 | if (false);
81 | else if (strncmp(SubstrateSafeMode_ "=", *env, sizeof(SubstrateSafeMode_)) == 0) {
82 | const char *value(*env + sizeof(SubstrateSafeMode_));
83 |
84 | if (false);
85 | else if (strcmp(value, "0") == 0 || strcmp(value, "NO") == 0)
86 | goto scan;
87 | else if (strcmp(value, "1") == 0 || strcmp(value, "YES") == 0 || strcmp(value, "") == 0)
88 | goto safe;
89 | else goto quit;
90 | }
91 |
92 |
93 | // DYLD_INSERT_LIBRARIES does not work in processes that are setugid
94 | // testing this condition prevents us from having a runaway test below
95 |
96 | struct stat info;
97 | if (_syscall(stat(path, &info)) == -1)
98 | goto safe;
99 | if ((info.st_mode & S_ISUID) != 0 && getuid() != info.st_uid)
100 | goto safe;
101 | // XXX: technically, if this user is not a member of the group
102 | if ((info.st_mode & S_ISGID) != 0 && getgid() != info.st_gid)
103 | goto safe;
104 |
105 |
106 | // some jailbreaks (example: iOS 3.0 PwnageTool) have broken (restrictive) sandbox patches
107 | // spawning the process with DYLD_INSERT_LIBRARIES causes them to immediately crash
108 |
109 | switch (pid_t child = _syscall(fork())) {
110 | case -1:
111 | goto quit;
112 |
113 | case 0:
114 | // XXX: figure out a way to turn off CrashReporter for this process
115 | _syscall(execle(path, path, NULL, (const char *[]) { SubstrateVariable_ "=" SubstrateLibrary_, "MSExitZero" "=", NULL }));
116 | _exit(EXIT_FAILURE);
117 |
118 | default:
119 | int status;
120 | if (_syscall(waitpid(child, &status, 0)) == -1)
121 | goto safe;
122 | if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS)
123 | goto safe;
124 | }
125 |
126 |
127 | scan:
128 | size_t size(0);
129 | for (char * const *env(envp); *env != NULL; ++env)
130 | ++size;
131 |
132 | char **envs(reinterpret_cast(malloc(sizeof(char *) * (size + 2))));
133 | if (envs == NULL)
134 | goto quit;
135 |
136 | size_t last(0);
137 |
138 |
139 | // fail is a goto target that can be used to deallocate our new environment and quit
140 |
141 | if (false) fail: {
142 | for (size_t i(0); i != last; ++i)
143 | free(envs[i]);
144 | free(envs);
145 | goto quit;
146 | }
147 |
148 |
149 | bool found(false);
150 |
151 | for (char * const *env(envp); *env != NULL; ++env) {
152 | const char *equal(strchr(*env, '='));
153 | if (equal == NULL)
154 | goto copy;
155 |
156 | #define envcmp(value) ( \
157 | (equal - *env == sizeof(value) - 1) && \
158 | strncmp(value, *env, sizeof(value) - 1) == 0 \
159 | )
160 |
161 | if (false);
162 | else if (envcmp("_MSLaunchHandle"))
163 | continue;
164 | else if (envcmp("_MSPosixSpawn"))
165 | continue;
166 | else if (envcmp(SubstrateVariable_)) {
167 | // if the variable is empty, let's just pretend we didn't find it (you with me? ;P)...
168 | // the problem is that the insanely hilarious code below doesn't work in this case
169 |
170 | if (equal[1] == '\0')
171 | continue;
172 | found = true;
173 |
174 |
175 | // our initial goal is to get a string :1:2:3: <- with leading and trailing colons
176 | // if we are adding the environment variable, then 1 will be the dylib being added
177 |
178 | const char *extra(safe ? "" : ":" SubstrateLibrary_);
179 |
180 | char *value;
181 | int count(asprintf(&value, "%s=%s:%s:", SubstrateVariable_, extra, equal + 1));
182 | if (count == -1)
183 | goto fail;
184 |
185 |
186 | // once that is complete, we will find the colon preceding the old content
187 | // this allows us to scan the string, removing any excess copies of :dylib
188 |
189 | // - strlen(equal + 1) <- subtract the bounded %s (orginal value)
190 | // - 1 - 1 <- subtract the leading and trailing colons around %s
191 |
192 | char *end(value + count);
193 | char *colon(end - 1 - strlen(equal + 1) - 1);
194 |
195 | for (char *scan(colon); (scan = strstr(scan, ":" SubstrateLibrary_ ":")) != NULL; ) {
196 | // end - scan <- all remaining characters
197 | // - sizeof(SubstrateLibrary_) <- subtract :dylib
198 | // + 1 <- add the null terminator
199 |
200 | memmove(scan, scan + sizeof(SubstrateLibrary_), end - scan - sizeof(SubstrateLibrary_) + 1);
201 |
202 | // move end of string back by :dylib length
203 |
204 | end -= sizeof(SubstrateLibrary_);
205 | }
206 |
207 |
208 | // if the variable is empty ("=:"), we just remove it entirely
209 | // end - value <- the total length of the string
210 |
211 | // sizeof(SubstrateVariable_) <- includes the =
212 | // + 1 <- we still need to compensate for the :
213 |
214 | if (end - value == sizeof(SubstrateVariable_) + 1) {
215 | free(value);
216 | continue;
217 | }
218 |
219 |
220 | // otherwise, we need to delete the leading and trailing colons
221 | // we reposition colon to the first colon (before our injection)
222 |
223 | colon = value + sizeof(SubstrateVariable_);
224 | memmove(colon, colon + 1, end - colon - 1);
225 | end[-2] = '\0';
226 | envs[last++] = value;
227 | continue;
228 | }
229 |
230 | copy:
231 | envs[last++] = strdup(*env);
232 | }
233 |
234 | if (!safe && !found)
235 | envs[last++] = strdup(SubstrateVariable_ "=" SubstrateLibrary_);
236 |
237 | envs[last++] = NULL;
238 |
239 | int value(_posix_spawn(pid, path, file_actions, attrp, argv, envs));
240 |
241 | for (char * const *env(envs); *env != NULL; ++env)
242 | free(*env);
243 | free(envs);
244 |
245 | return value;
246 | }
247 |
248 | template
249 | static void MSReinterpretAssign(Left_ &left, const Right_ &right) {
250 | left = reinterpret_cast(right);
251 | }
252 |
253 | MSInitialize {
254 | // this installation routine keeps a reference to the current library in _MSLaunchHandle
255 | // dlopen() is called now, and dlclose() will be called in the new version during upgrade
256 |
257 | Dl_info info;
258 | if (dladdr(reinterpret_cast(&$posix_spawn), &info) == 0)
259 | return;
260 | void *handle(dlopen(info.dli_fname, RTLD_NOLOAD));
261 |
262 |
263 | // before we unload the previous version, we hook posix_spawn to call our replacements
264 | // the original posix_spawn (from Apple) is kept in _MSPosixSpawn for use by new versions
265 |
266 | if (const char *cache = getenv("_MSPosixSpawn")) {
267 | MSReinterpretAssign(_posix_spawn, strtoull(cache, NULL, 0));
268 | MSHookFunction(&posix_spawn, &$posix_spawn);
269 | } else {
270 | MSHookFunction(&posix_spawn, MSHake(posix_spawn));
271 |
272 | char cache[32];
273 | sprintf(cache, "%p", _posix_spawn);
274 | setenv("_MSPosixSpawn", cache, false);
275 | }
276 |
277 |
278 | // specifically after having updated posix_spawn, we can unload the previous version
279 |
280 | if (const char *cache = getenv("_MSLaunchHandle")) {
281 | void *obsolete;
282 | MSReinterpretAssign(obsolete, strtoull(cache, NULL, 0));
283 | dlclose(obsolete);
284 | }
285 |
286 |
287 | // as installation has completed, we now set _MSLaunchHandle to the address of this version
288 |
289 | char cache[32];
290 | sprintf(cache, "%p", handle);
291 | // XXX: there is a race condition installing new versions: need atomic get/setenv()
292 | setenv("_MSLaunchHandle", cache, true);
293 | }
294 |
--------------------------------------------------------------------------------
/DarwinThreadInternal.hpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #ifndef SUBSTRATE_DARWINTHREADINTERNAL_HPP
23 | #define SUBSTRATE_DARWINTHREADINTERNAL_HPP
24 |
25 |
26 | // forces _pthread_setspecific_direct() to not call pthread_setspecific()
27 | // this is required to use thread local storage in trampolines and hooks
28 | // we save the old value here so we can restore it later in this file
29 |
30 | #ifndef __OPTIMIZE__
31 | #define MSNoOptimize
32 | #define __OPTIMIZE__
33 | #endif
34 |
35 |
36 | #include
37 |
38 |
39 | // we will now restore the original value of __OPTIMIZE__, for other code
40 |
41 | #ifdef MSNoOptimize
42 | #undef MSNoOptimize
43 | #undef __OPTIMIZE__
44 | #endif
45 |
46 | #endif//SUBSTRATE_DARWINTHREADINTERNAL_HPP
47 |
--------------------------------------------------------------------------------
/Debug.cpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #include "CydiaSubstrate.h"
23 | #include "Debug.hpp"
24 |
25 | #include
26 | #include
27 | #include
28 |
29 | _extern bool MSDebug;
30 | bool MSDebug = false;
31 |
32 | static char _MSHexChar(uint8_t value) {
33 | return value < 0x20 || value >= 0x80 ? '.' : value;
34 | }
35 |
36 | #define HexWidth_ 16
37 | #define HexDepth_ 4
38 |
39 | void MSLogHexEx(const void *vdata, size_t size, size_t stride, const char *mark) {
40 | const uint8_t *data((const uint8_t *) vdata);
41 |
42 | size_t i(0), j;
43 |
44 | char d[256];
45 | size_t b(0);
46 | d[0] = '\0';
47 |
48 | while (i != size) {
49 | if (i % HexWidth_ == 0) {
50 | if (mark != NULL)
51 | b += sprintf(d + b, "[%s] ", mark);
52 | b += sprintf(d + b, "0x%.3zx:", i);
53 | }
54 |
55 | b += sprintf(d + b, " ");
56 |
57 | for (size_t q(0); q != stride; ++q)
58 | b += sprintf(d + b, "%.2x", data[i + stride - q - 1]);
59 |
60 | i += stride;
61 |
62 | for (size_t q(1); q != stride; ++q)
63 | b += sprintf(d + b, " ");
64 |
65 | if (i % HexDepth_ == 0)
66 | b += sprintf(d + b, " ");
67 |
68 | if (i % HexWidth_ == 0) {
69 | b += sprintf(d + b, " ");
70 | for (j = i - HexWidth_; j != i; ++j)
71 | b += sprintf(d + b, "%c", _MSHexChar(data[j]));
72 |
73 | lprintf("%s", d);
74 | b = 0;
75 | d[0] = '\0';
76 | }
77 | }
78 |
79 | if (i % HexWidth_ != 0) {
80 | for (j = i % HexWidth_; j != HexWidth_; ++j)
81 | b += sprintf(d + b, " ");
82 | for (j = 0; j != (HexWidth_ - i % HexWidth_ + HexDepth_ - 1) / HexDepth_; ++j)
83 | b += sprintf(d + b, " ");
84 | b += sprintf(d + b, " ");
85 | for (j = i / HexWidth_ * HexWidth_; j != i; ++j)
86 | b += sprintf(d + b, "%c", _MSHexChar(data[j]));
87 |
88 | lprintf("%s", d);
89 | b = 0;
90 | d[0] = '\0';
91 | }
92 | }
93 |
94 | void MSLogHex(const void *vdata, size_t size, const char *mark) {
95 | return MSLogHexEx(vdata, size, 1, mark);
96 | }
97 |
--------------------------------------------------------------------------------
/Debug.hpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #ifndef SUBSTRATE_DEBUG_HPP
23 | #define SUBSTRATE_DEBUG_HPP
24 |
25 | #include "Log.hpp"
26 | #define lprintf(format, ...) \
27 | MSLog(MSLogLevelNotice, format, ## __VA_ARGS__)
28 |
29 | extern "C" bool MSDebug;
30 | void MSLogHexEx(const void *vdata, size_t size, size_t stride, const char *mark = 0);
31 | void MSLogHex(const void *vdata, size_t size, const char *mark = 0);
32 |
33 | #endif//SUBSTRATE_DEBUG_HPP
34 |
--------------------------------------------------------------------------------
/Environment.cpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #include
23 | #include
24 |
25 | #include "Log.hpp"
26 | #include "Environment.hpp"
27 |
28 | void MSClearEnvironment() {
29 | setenv(SubstrateSafeMode_, "1", true);
30 |
31 | char *dil(getenv(SubstrateVariable_));
32 | if (dil == NULL) {
33 | MSLog(MSLogLevelError, "MS:Error: %s is unset?", SubstrateVariable_);
34 | return;
35 | }
36 |
37 | size_t length(strlen(dil));
38 | char buffer[length + 3];
39 |
40 | buffer[0] = ':';
41 | memcpy(buffer + 1, dil, length);
42 | buffer[length + 1] = ':';
43 | buffer[length + 2] = '\0';
44 |
45 | char *index(strstr(buffer, ":" SubstrateLibrary_ ":"));
46 | if (index == NULL) {
47 | MSLog(MSLogLevelError, "MS:Error: dylib not in %s", SubstrateVariable_);
48 | return;
49 | }
50 |
51 | size_t skip(sizeof(SubstrateLibrary_));
52 | if (length == skip - 1) {
53 | unsetenv(SubstrateVariable_);
54 | return;
55 | }
56 |
57 | buffer[length + 1] = '\0';
58 | memmove(index + 1, index + 1 + skip, length - (index - buffer) - skip + 2);
59 | setenv(SubstrateVariable_, buffer + 1, true);
60 | }
61 |
--------------------------------------------------------------------------------
/Environment.hpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #ifndef SUBSTRATE_ENVIRONMENT_HPP
23 | #define SUBSTRATE_ENVIRONMENT_HPP
24 |
25 | #define SubstrateVariable_ "DYLD_INSERT_LIBRARIES"
26 | #define SubstrateLibrary_ "/Library/MobileSubstrate/MobileSubstrate.dylib"
27 |
28 | #define SubstrateSafeMode_ "_MSSafeMode"
29 |
30 | void MSClearEnvironment();
31 |
32 | #endif//SUBSTRATE_ENVIRONMENT_HPP
33 |
--------------------------------------------------------------------------------
/Info.plist:
--------------------------------------------------------------------------------
1 | CFBundlePackageType = "FMWK";
2 | CFBundleSignature = "????";
3 | CFBundleExecutable = "CydiaSubstrate";
4 | CFBundleIdentifier = "com.saurik.CydiaSubstate";
5 | CFBundleGetInfoString = "Cydia Substrate, SaurikIT LLC";
6 | CFBundleShortVersionString = "0.9";
7 | CFBundleInfoDictionaryVersion = "6.0";
8 | CFBundleName = "Cydia Substrate";
9 | CFBundleDevelopmentRegion = "English";
10 |
--------------------------------------------------------------------------------
/LaunchDaemons.hpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #ifndef SUBSTRATE_LAUNCHDAEMONS_HPP
23 | #define SUBSTRATE_LAUNCHDAEMONS_HPP
24 |
25 | #define SubstrateLaunchDaemons_ "/System/Library/LaunchDaemons"
26 | #define SubstrateLaunchConfig_ "/etc/launchd.conf"
27 |
28 | #define SubstrateLauncher_ "/Library/Frameworks/CydiaSubstrate.framework/Libraries/SubstrateLauncher.dylib"
29 | #define SubstrateBootstrapExecute_ "bsexec .. /usr/bin/cynject 1 " SubstrateLauncher_
30 |
31 | bool MSClearLaunchDaemons();
32 |
33 | #endif//SUBSTRATE_LAUNCHDAEMONS_HPP
34 |
--------------------------------------------------------------------------------
/LaunchDaemons.mm:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #include
23 |
24 | #include "Environment.hpp"
25 | #include "LaunchDaemons.hpp"
26 |
27 | // XXX: NO means "failed", false means "unneeded"
28 |
29 | static bool MSClearLaunchDaemon(NSString *file) {
30 | NSMutableDictionary *root([NSMutableDictionary dictionaryWithContentsOfFile:file]);
31 | if (root == nil)
32 | return NO;
33 |
34 | NSMutableDictionary *environment([root objectForKey:@"EnvironmentVariables"]);
35 | if (environment == nil)
36 | return false;
37 |
38 | NSString *variable([environment objectForKey:@ SubstrateVariable_]);
39 | if (variable == nil)
40 | return false;
41 |
42 | NSMutableArray *dylibs([[variable componentsSeparatedByString:@":"] mutableCopy]);
43 | if (dylibs == nil)
44 | return NO;
45 |
46 | NSUInteger index([dylibs indexOfObject:@ SubstrateLibrary_]);
47 | if (index == NSNotFound)
48 | return false;
49 |
50 | [dylibs removeObject:@ SubstrateLibrary_];
51 |
52 | if ([dylibs count] != 0)
53 | [environment setObject:[dylibs componentsJoinedByString:@":"] forKey:@ SubstrateVariable_];
54 | else if ([environment count] == 1)
55 | [root removeObjectForKey:@"EnvironmentVariables"];
56 | else
57 | [environment removeObjectForKey:@ SubstrateVariable_];
58 |
59 | NSString *error;
60 | NSData *data([NSPropertyListSerialization dataFromPropertyList:root format:NSPropertyListBinaryFormat_v1_0 errorDescription:&error]);
61 | if (data == nil)
62 | return NO;
63 |
64 | if (![data writeToFile:file atomically:YES])
65 | return NO;
66 |
67 | return true;
68 | }
69 |
70 | bool MSClearLaunchDaemons() {
71 | NSError *error;
72 |
73 | NSArray *contents([[NSFileManager defaultManager] contentsOfDirectoryAtPath:@ SubstrateLaunchDaemons_ error:&error]);
74 | if (contents == nil)
75 | return NO;
76 |
77 | bool cleared(false);
78 |
79 | // XXX: this should filter to only files
80 | for (NSString *file in contents)
81 | cleared |= MSClearLaunchDaemon([@ SubstrateLaunchDaemons_ stringByAppendingPathComponent:file]);
82 |
83 | return cleared;
84 | }
85 |
--------------------------------------------------------------------------------
/Log.hpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #ifndef SUBSTRATE_LOG_HPP
23 | #define SUBSTRATE_LOG_HPP
24 |
25 | #if 0
26 |
27 | #include
28 |
29 | #define MSLog(level, format, ...) CFLog(level, CFSTR(format), ## __VA_ARGS__)
30 |
31 | #define MSLogLevelNotice kCFLogLevelNotice
32 | #define MSLogLevelWarning kCFLogLevelWarning
33 | #define MSLogLevelError kCFLogLevelError
34 |
35 | #else
36 |
37 | #include
38 |
39 | #if __COREFOUNDATION__
40 |
41 | #define MSLog(level, format, ...) do { \
42 | CFStringRef _formatted(CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR(format), ## __VA_ARGS__)); \
43 | size_t _size(CFStringGetMaximumSizeForEncoding(CFStringGetLength(_formatted), kCFStringEncodingUTF8)); \
44 | char _utf8[_size + sizeof('\0')]; \
45 | CFStringGetCString(_formatted, _utf8, sizeof(_utf8), kCFStringEncodingUTF8); \
46 | CFRelease(_formatted); \
47 | syslog(level, "%s", _utf8); \
48 | } while (false)
49 |
50 | #else
51 |
52 | #define MSLog(level, format, ...) do { \
53 | syslog(level, format, ## __VA_ARGS__); \
54 | } while (false)
55 |
56 | #endif
57 |
58 | #define MSLogLevelNotice LOG_NOTICE
59 | #define MSLogLevelWarning LOG_WARNING
60 | #define MSLogLevelError LOG_ERR
61 |
62 | #endif
63 |
64 | #endif//SUBSTRATE_LOG_HPP
65 |
--------------------------------------------------------------------------------
/MachInterface.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 | set -o pipefail
5 |
6 | user=$1
7 | header=$2
8 | defs=$3
9 |
10 | mig -arch i386 -server /dev/null -user /dev/stdout -header "${header}" "${defs}" | sed -e $'
11 | /^mig_external kern_return_t / {
12 | n;
13 | n;
14 | x;
15 | s/.*/\tmach_msg_id_t msgh_id,/;
16 | p;
17 | s/.*/\tmach_port_t reply_port,/;
18 | p;
19 | x;
20 | };
21 |
22 | s/^\\(mig_internal kern_return_t __MIG_check__Reply__[^(]*(\\)/\\1mach_msg_id_t msgh_id, /;
23 | s/\\(check_result = __MIG_check__Reply__[^(]*(\\)/\\1msgh_id, /;
24 |
25 | s/mig_get_reply_port()/reply_port/g;
26 | s/31337\\([0-9][0-9]\\)/msgh_id/g;
27 | s/31338\\([0-9][0-9]\\)/(msgh_id + 100)/g;
28 | ' >"${user}" || rm -f "${user}"
29 |
--------------------------------------------------------------------------------
/MachMemory.cpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #define SubstrateInternal
23 | #include "CydiaSubstrate.h"
24 |
25 | #include "Log.hpp"
26 |
27 | #include
28 | #include
29 |
30 | #include
31 | #include
32 |
33 | #include
34 |
35 | #ifdef __arm__
36 |
37 | #include "MachMessage.hpp"
38 |
39 | static mach_msg_return_t MS_mach_msg(mach_msg_header_t *msg, mach_msg_option_t option, mach_msg_size_t send_size, mach_msg_size_t rcv_size, mach_port_name_t rcv_name, mach_msg_timeout_t timeout, mach_port_name_t notify) {
40 | for (;;) switch (mach_msg_return_t error = MS_mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, timeout, notify)) {
41 | case MACH_SEND_INTERRUPT:
42 | break;
43 |
44 | case MACH_RCV_INTERRUPT:
45 | option &= ~MACH_SEND_MSG;
46 | break;
47 |
48 | default:
49 | return error;
50 | }
51 | }
52 |
53 | #define mach_msg MS_mach_msg
54 | #include "MachProtect.h"
55 | #include "MachProtect.c"
56 | #undef mach_msg
57 |
58 | static kern_return_t MS_vm_protect(mach_port_t reply_port, vm_map_t target_task, vm_address_t address, vm_size_t size, boolean_t set_maximum, vm_prot_t new_protection) {
59 | kern_return_t error;
60 |
61 |
62 | #if 0
63 | // on iOS >= 5.0, Apple now provides a number of system call traps for common mach interfaces, like vm_map
64 | // XXX: this code, when tested on iOS 2.2 (not tested on >> 2.2 && << 5.0) returns 0x807 with signal "?"
65 |
66 | error = MS_vm_protect_trap(target_task, address, size, set_maximum, new_protection);
67 | if (error != MACH_SEND_INVALID_DEST)
68 | return error;
69 | #endif
70 |
71 |
72 | // 3803 is vm_map's vm_protect. it is guaranteed to take 32-bit arguments on all platforms, which is convenient
73 | // unfortunately, this kernel-side interface seems to be missing on at least iOS 4.0, so we cannot rely on it
74 |
75 | error = MS_vm_protect_mach(3803, reply_port, target_task, address, size, set_maximum, new_protection);
76 | if (error != MIG_BAD_ID)
77 | return error;
78 |
79 |
80 | // 4802 is mach_vm's mach_vm_protect. it is supposed to always take "the largest size type for the platform"
81 | // unfortunately, while on iOS << 5.0 ARM was considered 32-bit, with iOS 5.0 Apple decided ARM could be 64-bit
82 | // therefore, we cannot know what size arguments to pass to this function, and Apple has nigh unto deprecated it
83 | // thankfully, current devices that have a 64-bit mach_vm_protect also support the 32-bit vm_protect interface
84 |
85 | error = MS_vm_protect_mach(4802, reply_port, target_task, address, size, set_maximum, new_protection);
86 | if (error != MIG_BAD_ID)
87 | return error;
88 |
89 |
90 | return error;
91 | }
92 |
93 | #else
94 |
95 | #define MS_vm_protect(a0, a1, a2, a3, a4, a5) vm_protect(a1, a2, a3, a4, a5)
96 |
97 | #endif
98 |
99 | struct __SubstrateMemory {
100 | mach_port_t reply_;
101 | mach_port_t self_;
102 | uintptr_t base_;
103 | size_t width_;
104 |
105 | __SubstrateMemory(mach_port_t reply, mach_port_t self, uintptr_t base, size_t width) :
106 | reply_(reply),
107 | self_(self),
108 | base_(base),
109 | width_(width)
110 | {
111 | }
112 | };
113 |
114 | extern "C" SubstrateMemoryRef SubstrateMemoryCreate(SubstrateAllocatorRef allocator, SubstrateProcessRef process, void *data, size_t size) {
115 | if (allocator != NULL) {
116 | MSLog(MSLogLevelError, "MS:Error:allocator != NULL");
117 | return NULL;
118 | }
119 |
120 | if (size == 0)
121 | return NULL;
122 |
123 | int page(getpagesize());
124 |
125 | mach_port_t reply(mig_get_reply_port());
126 | mach_port_t self(mach_task_self());
127 |
128 | uintptr_t base(reinterpret_cast(data) / page * page);
129 | size_t width(((reinterpret_cast(data) + size - 1) / page + 1) * page - base);
130 |
131 |
132 | // the max_protection of this memory, on ARM, is normally r-x (as it is currently executable and marked clean)
133 | // however, we need to write to it; mprotect() can't do it, so we use vm_protect(VM_PROT_COPY), to get a new page
134 |
135 | // XXX: I should try for RWX here, but it seriously never works and you get this irritating log:
136 | // kernel[0] : EMBEDDED: vm_map_protect can't have both write and exec at the same time
137 |
138 | if (kern_return_t error = MS_vm_protect(reply, self, base, width, FALSE, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY)) {
139 | MSLog(MSLogLevelError, "MS:Error:vm_protect() = %d", error);
140 | return NULL;
141 | }
142 |
143 |
144 | return new __SubstrateMemory(reply, self, base, width);
145 | }
146 |
147 | extern "C" void SubstrateMemoryRelease(SubstrateMemoryRef memory) {
148 | if (kern_return_t error = MS_vm_protect(memory->reply_, memory->self_, memory->base_, memory->width_, FALSE, VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY))
149 | MSLog(MSLogLevelError, "MS:Error:vm_protect() = %d", error);
150 |
151 |
152 | // Apple removed __clear_cache in iOS 4.1, so we can't rely on it here
153 | // however, it also was always a nop, and as no never really worked...
154 |
155 | sys_dcache_flush(reinterpret_cast(memory->base_), memory->width_);
156 | sys_icache_invalidate(reinterpret_cast(memory->base_), memory->width_);
157 |
158 |
159 | delete memory;
160 | }
161 |
--------------------------------------------------------------------------------
/MachMessage.cpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #include
23 |
24 | #ifdef __arm__
25 |
26 | __attribute__((__naked__))
27 | __attribute__((__noinline__))
28 | mach_msg_return_t MS_mach_msg_trap(mach_msg_header_t *, mach_msg_option_t, mach_msg_size_t, mach_msg_size_t, mach_port_name_t, mach_msg_timeout_t, mach_port_name_t) {
29 | register mach_msg_return_t error asm("r0");
30 |
31 | asm volatile (
32 | "mov r12, sp\n"
33 | "push.w {r4, r5, r6, r8}\n"
34 | "ldm.w r12, {r4, r5, r6}\n"
35 | "mvn.w r12, #30\n"
36 | "svc 0x80\n"
37 | "pop.w {r4, r5, r6, r8}\n"
38 | : "=a" (error)
39 | :
40 | : "r1", "r2", "r3", "r4", "r5", "r6", "r8", "r12"
41 | );
42 |
43 | return error;
44 | }
45 |
46 | __attribute__((__naked__))
47 | __attribute__((__noinline__))
48 | mach_msg_return_t MS_vm_protect_trap(vm_map_t target_task, vm_address_t address, vm_size_t size, boolean_t set_maximum, vm_prot_t new_protection) {
49 | register mach_msg_return_t error asm("r0");
50 |
51 | asm volatile (
52 | "mov r12, sp\n"
53 | "push {r4, r5}\n"
54 | "ldr.w r4, [r12]\n"
55 | "mvn.w r12, #14\n"
56 | "svc 0x80\n"
57 | "pop {r4, r5}\n"
58 | : "=a" (error)
59 | :
60 | : "r1", "r2", "r3", "r4", "r5", "r12"
61 | );
62 |
63 | return error;
64 | }
65 |
66 | #endif
67 |
--------------------------------------------------------------------------------
/MachMessage.hpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #ifndef SUBSTRATE_MACHMESSAGE_HPP
23 | #define SUBSTRATE_MACHMESSAGE_HPP
24 |
25 | #ifdef __arm__
26 | extern mach_msg_return_t MS_mach_msg_trap(mach_msg_header_t *, mach_msg_option_t, mach_msg_size_t, mach_msg_size_t, mach_port_name_t, mach_msg_timeout_t, mach_port_name_t);
27 | extern mach_msg_return_t MS_vm_protect_trap(vm_map_t, vm_address_t, vm_size_t, boolean_t, vm_prot_t);
28 | #else
29 | extern "C" mach_msg_return_t mach_msg_trap(mach_msg_header_t *, mach_msg_option_t, mach_msg_size_t, mach_msg_size_t, mach_port_name_t, mach_msg_timeout_t, mach_port_name_t);
30 | #define MS_mach_msg_trap mach_msg_trap
31 |
32 | static _finline MS_vm_protect_trap(vm_map_t, vm_address_t, vm_size_t, boolean_t, vm_prot_t) {
33 | return MACH_SEND_INVALID_DEST;
34 | }
35 | #endif
36 |
37 | #endif//SUBSTRATE_MACHMESSAGE_HPP
38 |
--------------------------------------------------------------------------------
/MachProtect.defs:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | subsystem MS_vm_map 3133700;
5 |
6 | routine MS_vm_protect_mach(
7 | target_task : vm_task_entry_t;
8 | address : vm_address_t;
9 | size : vm_size_t;
10 | set_maximum : boolean_t;
11 | new_protection : vm_prot_t);
12 |
--------------------------------------------------------------------------------
/MobileSafety.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r-plus/substrate/904d20f414c79a2716680f4d29d833e6ce0dcea2/MobileSafety.jpg
--------------------------------------------------------------------------------
/MobileSafety.mm:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | %apt Package: com.saurik.substrate.safemode
23 | %apt Author: Jay Freeman (saurik)
24 |
25 | %apt Name: Substrate Safe Mode
26 | %apt Description: safe mode safety extension (safe)
27 |
28 | %apt Depends: mobilesubstrate (>= 0.9.3367+38)
29 |
30 | %fflag 1
31 | %fflag 2
32 |
33 | %bundle com.apple.springboard
34 |
35 | %flag -framework Foundation
36 | %flag -framework UIKit
37 |
38 | #import
39 | #import
40 | #import
41 | #import
42 |
43 | #include "CydiaSubstrate.h"
44 |
45 | MSClassHook(UIStatusBar)
46 |
47 | MSClassHook(UIImage)
48 | MSMetaClassHook(UIImage)
49 |
50 | MSClassHook(AAAccountManager)
51 | MSMetaClassHook(AAAccountManager)
52 |
53 | MSClassHook(BBSectionInfo)
54 |
55 | MSClassHook(SBAlertItemsController)
56 | MSClassHook(SBButtonBar)
57 | MSClassHook(SBIconController)
58 | MSClassHook(SBStatusBar)
59 | MSClassHook(SBStatusBarDataManager)
60 | MSClassHook(SBStatusBarTimeView)
61 | MSClassHook(SBUIController)
62 |
63 | Class $SafeModeAlertItem;
64 |
65 | @interface SBAlertItem : NSObject {
66 | }
67 | - (UIAlertView *) alertSheet;
68 | - (void) dismiss;
69 | @end
70 |
71 | @interface SBAlertItemsController : NSObject {
72 | }
73 | + (SBAlertItemsController *) sharedInstance;
74 | - (void) activateAlertItem:(SBAlertItem *)item;
75 | @end
76 |
77 | @interface SBStatusBarTimeView : UIView {
78 | }
79 | - (id) textFont;
80 | @end
81 |
82 | @interface UIApplication (CydiaSubstrate)
83 | - (void) applicationOpenURL:(id)url;
84 | @end
85 |
86 | @interface UIAlertView (CydiaSubstrate)
87 | - (void) setForceHorizontalButtonsLayout:(BOOL)force;
88 | - (void) setBodyText:(NSString *)body;
89 | - (void) setNumberOfRows:(NSInteger)rows;
90 | @end
91 |
92 | void SafeModeAlertItem$alertSheet$buttonClicked$(id self, SEL sel, id sheet, int button) {
93 | switch (button) {
94 | case 1:
95 | break;
96 |
97 | case 2:
98 | // XXX: there are better ways of restarting SpringBoard that would actually save state
99 | exit(0);
100 | break;
101 |
102 | case 3:
103 | [[UIApplication sharedApplication] applicationOpenURL:[NSURL URLWithString:@"http://cydia.saurik.com/safemode/"]];
104 | break;
105 | }
106 |
107 | [self dismiss];
108 | }
109 |
110 | void SafeModeAlertItem$configure$requirePasscodeForActions$(id self, SEL sel, BOOL configure, BOOL require) {
111 | UIAlertView *sheet([self alertSheet]);
112 |
113 | [sheet setDelegate:self];
114 | [sheet setBodyText:@"We apologize for the inconvenience, but SpringBoard has just crashed.\n\nMobileSubstrate /did not/ cause this problem: it has protected you from it.\n\nYour device is now running in Safe Mode. All extensions that support this safety system are disabled.\n\nReboot (or restart SpringBoard) to return to the normal mode. To return to this dialog touch the status bar.\n\nTap \"Help\" below for more tips."];
115 | [sheet addButtonWithTitle:@"OK"];
116 | [sheet addButtonWithTitle:@"Restart"];
117 | [sheet addButtonWithTitle:@"Help"];
118 | [sheet setNumberOfRows:1];
119 |
120 | if ([sheet respondsToSelector:@selector(setForceHorizontalButtonsLayout:)])
121 | [sheet setForceHorizontalButtonsLayout:YES];
122 | }
123 |
124 | void SafeModeAlertItem$performUnlockAction(id self, SEL sel) {
125 | [[$SBAlertItemsController sharedInstance] activateAlertItem:self];
126 | }
127 |
128 | static void MSAlert() {
129 | if ($SafeModeAlertItem == nil)
130 | $SafeModeAlertItem = objc_lookUpClass("SafeModeAlertItem");
131 | if ($SafeModeAlertItem == nil) {
132 | $SafeModeAlertItem = objc_allocateClassPair(objc_getClass("SBAlertItem"), "SafeModeAlertItem", 0);
133 | if ($SafeModeAlertItem == nil)
134 | return;
135 |
136 | class_addMethod($SafeModeAlertItem, @selector(alertSheet:buttonClicked:), (IMP) &SafeModeAlertItem$alertSheet$buttonClicked$, "v@:@i");
137 | class_addMethod($SafeModeAlertItem, @selector(configure:requirePasscodeForActions:), (IMP) &SafeModeAlertItem$configure$requirePasscodeForActions$, "v@:cc");
138 | class_addMethod($SafeModeAlertItem, @selector(performUnlockAction), (IMP) SafeModeAlertItem$performUnlockAction, "v@:");
139 | objc_registerClassPair($SafeModeAlertItem);
140 | }
141 |
142 | if ($SBAlertItemsController != nil)
143 | [[$SBAlertItemsController sharedInstance] activateAlertItem:[[[$SafeModeAlertItem alloc] init] autorelease]];
144 | }
145 |
146 |
147 | // XXX: on iOS 5.0, we really would prefer avoiding
148 |
149 | MSInstanceMessageHook2(void, SBStatusBar, touchesEnded,withEvent, id, touches, id, event) {
150 | MSAlert();
151 | MSOldCall(touches, event);
152 | }
153 |
154 | MSInstanceMessageHook1(void, SBStatusBar, mouseDown, void *, event) {
155 | MSAlert();
156 | MSOldCall(event);
157 | }
158 |
159 | MSInstanceMessageHook2(void, UIStatusBar, touchesBegan,withEvent, void *, touches, void *, event) {
160 | MSAlert();
161 | MSOldCall(touches, event);
162 | }
163 |
164 |
165 | // this fairly complex code came from Grant, to solve the "it Safe Mode"-in-bar bug
166 |
167 | MSInstanceMessageHook0(void, SBStatusBarDataManager, _updateTimeString) {
168 | char *_data(&MSHookIvar(self, "_data"));
169 | if (_data == NULL)
170 | return;
171 |
172 | Ivar _itemIsEnabled(object_getInstanceVariable(self, "_itemIsEnabled", NULL));
173 | if (_itemIsEnabled == NULL)
174 | return;
175 |
176 | Ivar _itemIsCloaked(object_getInstanceVariable(self, "_itemIsCloaked", NULL));
177 | if (_itemIsCloaked == NULL)
178 | return;
179 |
180 | size_t enabledOffset(ivar_getOffset(_itemIsEnabled));
181 | size_t cloakedOffset(ivar_getOffset(_itemIsCloaked));
182 | if (enabledOffset >= cloakedOffset)
183 | return;
184 |
185 | size_t offset(cloakedOffset - enabledOffset);
186 | char *timeString(_data + offset);
187 | strcpy(timeString, "Exit Safe Mode");
188 | }
189 |
190 |
191 | static bool alerted_;
192 |
193 | static void AlertIfNeeded() {
194 | if (alerted_)
195 | return;
196 | alerted_ = true;
197 | MSAlert();
198 | }
199 |
200 |
201 | // on iOS 4.3 and above we can use this advertisement, which seems to check every time the user unlocks
202 | // XXX: verify that this still works on iOS 5.0
203 |
204 | MSClassMessageHook0(void, AAAccountManager, showMobileMeOfferIfNecessary) {
205 | AlertIfNeeded();
206 | }
207 |
208 |
209 | // -[SBIconController showInfoAlertIfNeeded] explains how to drag icons around the iPhone home screen
210 | // it used to be shown to users when they unlocked their screen for the first time, and happened every unlock
211 | // however, as of iOS 4.3, it got relegated to only appearing once the user installed an app or web clip
212 |
213 | MSInstanceMessageHook0(void, SBIconController, showInfoAlertIfNeeded) {
214 | AlertIfNeeded();
215 | }
216 |
217 |
218 | // the icon state, including crazy configurations like Five Icon Dock, is stored in SpringBoard's defaults
219 | // unfortunately, SpringBoard on iOS 2.0 and 2.1 (maybe 2.2 as well) buffer overrun with more than 4 icons
220 | // there is a third party package called IconSupport that remedies this, but not everyone is using it yet
221 |
222 | MSInstanceMessageHook0(int, SBButtonBar, maxIconColumns) {
223 | static int max;
224 | if (max == 0) {
225 | max = MSOldCall();
226 | if (NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults])
227 | if (NSDictionary *iconState = [defaults objectForKey:@"iconState"])
228 | if (NSDictionary *buttonBar = [iconState objectForKey:@"buttonBar"])
229 | if (NSArray *iconMatrix = [buttonBar objectForKey:@"iconMatrix"])
230 | if ([iconMatrix count] != 0)
231 | if (NSArray *row = [iconMatrix objectAtIndex:0]) {
232 | int count([row count]);
233 | if (max < count)
234 | max = count;
235 | }
236 | } return max;
237 | }
238 |
239 |
240 | MSInstanceMessageHook0(id, SBUIController, init) {
241 | if ((self = MSOldCall()) != nil) {
242 | UIView *&_contentLayer(MSHookIvar(self, "_contentLayer"));
243 | UIView *&_contentView(MSHookIvar(self, "_contentView"));
244 |
245 | UIView *layer;
246 | if (&_contentLayer != NULL)
247 | layer = _contentLayer;
248 | else if (&_contentView != NULL)
249 | layer = _contentView;
250 | else
251 | layer = nil;
252 |
253 | if (layer != nil)
254 | [layer setBackgroundColor:[UIColor darkGrayColor]];
255 | } return self;
256 | }
257 |
258 | #define Paper_ "/Library/MobileSubstrate/MobileSafety.png"
259 |
260 | MSClassMessageHook0(UIImage *, UIImage, defaultDesktopImage) {
261 | return [UIImage imageWithContentsOfFile:@Paper_];
262 | }
263 |
264 | MSInstanceMessageHook0(void, SBStatusBarTimeView, tile) {
265 | NSString *&_time(MSHookIvar(self, "_time"));
266 | CGRect &_textRect(MSHookIvar(self, "_textRect"));
267 | if (_time != nil)
268 | [_time release];
269 | _time = [@"Exit Safe Mode" retain];
270 | id font([self textFont]);
271 | CGSize size([_time sizeWithFont:font]);
272 | CGRect frame([self frame]);
273 | _textRect.size = size;
274 | _textRect.origin.x = (frame.size.width - size.width) / 2;
275 | _textRect.origin.y = (frame.size.height - size.height) / 2;
276 | }
277 |
278 |
279 | // notification widgets ("wee apps" or "bulletin board sections") are capable of crashing SpringBoard
280 | // unfortunately, which ones are in use are stored in SpringBoard's defaults, so we need to turn them off
281 |
282 | MSInstanceMessageHook0(BOOL, BBSectionInfo, showsInNotificationCenter) {
283 | return NO;
284 | }
285 |
--------------------------------------------------------------------------------
/MobileSafety.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r-plus/substrate/904d20f414c79a2716680f4d29d833e6ce0dcea2/MobileSafety.png
--------------------------------------------------------------------------------
/ObjectiveC.cpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #include "CydiaSubstrate.h"
23 |
24 | // XXX: this is required by some code below
25 | #ifdef __arm__
26 | #include "ARM.hpp"
27 | #elif defined(__i386__) || defined(__x86_64__)
28 | #include "x86.hpp"
29 | #endif
30 |
31 | #include
32 |
33 | #include
34 | #include
35 | #include
36 |
37 | #include
38 | #include
39 |
40 | #include "Debug.hpp"
41 | #include "Log.hpp"
42 |
43 | extern "C" void *NSPushAutoreleasePool(unsigned);
44 | extern "C" void NSPopAutoreleasePool(void *);
45 |
46 | static Method MSFindMethod(Class _class, SEL sel) {
47 | for (; _class != nil; _class = class_getSuperclass(_class)) {
48 | unsigned int size;
49 | Method *methods(class_copyMethodList(_class, &size));
50 | if (methods == NULL)
51 | continue;
52 |
53 | for (unsigned int j(0); j != size; ++j) {
54 | Method method(methods[j]);
55 | if (!sel_isEqual(method_getName(methods[j]), sel))
56 | continue;
57 |
58 | free(methods);
59 | return method;
60 | }
61 |
62 | free(methods);
63 | }
64 |
65 | return nil;
66 | }
67 |
68 | static void MSHookMessageInternal(Class _class, SEL sel, IMP imp, IMP *result, const char *prefix) {
69 | if (MSDebug)
70 | MSLog(MSLogLevelNotice, "MSHookMessageInternal(%s, %s, %p, %p, \"%s\")",
71 | _class == nil ? "nil" : class_getName(_class),
72 | sel == NULL ? "NULL" : sel_getName(sel),
73 | imp, result, prefix
74 | );
75 | if (_class == nil) {
76 | MSLog(MSLogLevelWarning, "MS:Warning: nil class argument");
77 | return;
78 | } else if (sel == nil) {
79 | MSLog(MSLogLevelWarning, "MS:Warning: nil sel argument");
80 | return;
81 | } else if (imp == nil) {
82 | MSLog(MSLogLevelWarning, "MS:Warning: nil imp argument");
83 | return;
84 | }
85 |
86 | Method method(MSFindMethod(_class, sel));
87 | if (method == nil) {
88 | MSLog(MSLogLevelWarning, "MS:Warning: message not found [%s %s]", class_getName(_class), sel_getName(sel));
89 | return;
90 | }
91 |
92 | const char *type(method_getTypeEncoding(method));
93 |
94 | bool direct(false);
95 |
96 | unsigned count;
97 | Method *methods(class_copyMethodList(_class, &count));
98 | for (unsigned i(0); i != count; ++i)
99 | if (methods[i] == method) {
100 | direct = true;
101 | break;
102 | }
103 | free(methods);
104 |
105 | IMP old(NULL);
106 |
107 | if (!direct) {
108 | #if defined(__arm__)
109 | size_t length(11 * sizeof(uint32_t));
110 | #elif defined(__i386__)
111 | size_t length(20);
112 | #elif defined(__x86_64__)
113 | size_t length(50);
114 | #endif
115 |
116 | uint32_t *buffer(reinterpret_cast(mmap(
117 | NULL, length, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0
118 | )));
119 |
120 | if (buffer == MAP_FAILED)
121 | MSLog(MSLogLevelError, "MS:Error:mmap() = %d", errno);
122 | else if (false) fail:
123 | munmap(buffer, length);
124 | else {
125 | Class super(class_getSuperclass(_class));
126 |
127 | #if defined(__arm__)
128 | buffer[ 0] = A$stmdb_sp$_$rs$((1 << A$r0) | (1 << A$r1) | (1 << A$r2) | (1 << A$r3) | (1 << A$lr));
129 | buffer[ 1] = A$ldr_rd_$rn_im$(A$r0, A$pc, ( 8 - 1 - 2) * 4);
130 | buffer[ 2] = A$ldr_rd_$rn_im$(A$r1, A$pc, ( 9 - 2 - 2) * 4);
131 | buffer[ 3] = A$ldr_rd_$rn_im$(A$lr, A$pc, (10 - 3 - 2) * 4);
132 | buffer[ 4] = A$blx_rm(A$lr);
133 | buffer[ 5] = A$str_rd_$rn_im$(A$r0, A$sp, -4);
134 | buffer[ 6] = A$ldmia_sp$_$rs$((1 << A$r0) | (1 << A$r1) | (1 << A$r2) | (1 << A$r3) | (1 << A$lr));
135 | buffer[ 7] = A$ldr_rd_$rn_im$(A$pc, A$sp, -4 - (5 * 4));
136 | buffer[ 8] = reinterpret_cast(super);
137 | buffer[ 9] = reinterpret_cast(sel);
138 | buffer[10] = reinterpret_cast(&class_getMethodImplementation);
139 | #elif defined(__i386__)
140 | uint8_t *current(reinterpret_cast(buffer));
141 |
142 | MSPushPointer(current, sel);
143 | MSPushPointer(current, super);
144 | MSWriteCall(current, &class_getMethodImplementation);
145 | MSWriteAdd(current, I$rsp, 8);
146 | MSWriteJump(current, I$rax);
147 | #elif defined(__x86_64__)
148 | uint8_t *current(reinterpret_cast(buffer));
149 |
150 | MSWritePush(current, I$rdi);
151 | MSWritePush(current, I$rsi);
152 | MSWritePush(current, I$rdx);
153 |
154 | MSWritePush(current, I$rcx);
155 | MSWritePush(current, I$r8);
156 | MSWritePush(current, I$r9);
157 |
158 | MSWriteSet64(current, I$rdi, super);
159 | MSWriteSet64(current, I$rsi, sel);
160 |
161 | MSWriteSet64(current, I$rax, &class_getMethodImplementation);
162 | MSWriteCall(current, I$rax);
163 |
164 | MSWritePop(current, I$r9);
165 | MSWritePop(current, I$r8);
166 | MSWritePop(current, I$rcx);
167 |
168 | MSWritePop(current, I$rdx);
169 | MSWritePop(current, I$rsi);
170 | MSWritePop(current, I$rdi);
171 |
172 | MSWriteJump(current, I$rax);
173 | #endif
174 |
175 | if (mprotect(buffer, length, PROT_READ | PROT_EXEC) == -1) {
176 | MSLog(MSLogLevelError, "MS:Error:mprotect():%d", errno);
177 | goto fail;
178 | }
179 |
180 | old = reinterpret_cast(buffer);
181 |
182 | if (MSDebug) {
183 | char name[16];
184 | sprintf(name, "%p", old);
185 | MSLogHex(buffer, length, name);
186 | MSLog(MSLogLevelNotice, "jmp %p(%p, %p)", &class_getMethodImplementation, super, sel);
187 | }
188 | }
189 | }
190 |
191 | if (old == NULL)
192 | old = method_getImplementation(method);
193 |
194 | if (result != NULL)
195 | *result = old;
196 |
197 | if (prefix != NULL) {
198 | const char *name(sel_getName(sel));
199 | size_t namelen(strlen(name));
200 | size_t fixlen(strlen(prefix));
201 |
202 | char *newname(reinterpret_cast(alloca(fixlen + namelen + 1)));
203 | memcpy(newname, prefix, fixlen);
204 | memcpy(newname + fixlen, name, namelen + 1);
205 |
206 | if (!class_addMethod(_class, sel_registerName(newname), old, type))
207 | MSLog(MSLogLevelError, "MS:Error: failed to rename [%s %s]", class_getName(_class), name);
208 | }
209 |
210 | if (direct)
211 | method_setImplementation(method, imp);
212 | else
213 | class_addMethod(_class, sel, imp, type);
214 | }
215 |
216 | _extern void MSHookMessageEx(Class _class, SEL sel, IMP imp, IMP *result) {
217 | MSHookMessageInternal(_class, sel, imp, result, NULL);
218 | }
219 |
220 | #ifdef __arm__
221 | _extern IMP MSHookMessage(Class _class, SEL sel, IMP imp, const char *prefix) {
222 | IMP result(NULL);
223 | MSHookMessageInternal(_class, sel, imp, &result, prefix);
224 | return result;
225 | }
226 | #endif
227 |
228 | #ifdef __arm__
229 | _extern void _Z13MSHookMessageP10objc_classP13objc_selectorPFP11objc_objectS4_S2_zEPKc(Class _class, SEL sel, IMP imp, const char *prefix) {
230 | MSHookMessageInternal(_class, sel, imp, NULL, prefix);
231 | }
232 | #endif
233 |
--------------------------------------------------------------------------------
/PosixMemory.cpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #define SubstrateInternal
23 | #include "CydiaSubstrate.h"
24 |
25 | #include "Log.hpp"
26 |
27 | #include
28 |
29 | #include
30 | #include
31 | #include
32 |
33 | extern "C" void __clear_cache (void *beg, void *end);
34 |
35 | struct __SubstrateMemory {
36 | void *address_;
37 | size_t width_;
38 |
39 | __SubstrateMemory(void *address, size_t width) :
40 | address_(address),
41 | width_(width)
42 | {
43 | }
44 | };
45 |
46 | extern "C" SubstrateMemoryRef SubstrateMemoryCreate(SubstrateAllocatorRef allocator, SubstrateProcessRef process, void *data, size_t size) {
47 | if (allocator != NULL) {
48 | MSLog(MSLogLevelError, "MS:Error:allocator != NULL");
49 | return NULL;
50 | }
51 |
52 | if (size == 0)
53 | return NULL;
54 |
55 | int page(getpagesize());
56 |
57 | uintptr_t base(reinterpret_cast(data) / page * page);
58 | size_t width(((reinterpret_cast(data) + size - 1) / page + 1) * page - base);
59 | void *address(reinterpret_cast(base));
60 |
61 | if (mprotect(address, width, PROT_READ | PROT_WRITE | PROT_EXEC) == -1) {
62 | MSLog(MSLogLevelError, "MS:Error:mprotect() = %d", errno);
63 | return NULL;
64 | }
65 |
66 | return new __SubstrateMemory(address, width);
67 | }
68 |
69 | extern "C" void SubstrateMemoryRelease(SubstrateMemoryRef memory) {
70 | if (mprotect(memory->address_, memory->width_, PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
71 | MSLog(MSLogLevelError, "MS:Error:mprotect() = %d", errno);
72 |
73 | __clear_cache(reinterpret_cast(memory->address_), reinterpret_cast(memory->address_) + memory->width_);
74 |
75 | delete memory;
76 | }
77 |
--------------------------------------------------------------------------------
/TestSuperCall.mm:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #include
23 | #include "CydiaSubstrate.h"
24 |
25 | struct dat {
26 | uint32_t a;
27 | uint32_t b;
28 | uint32_t c;
29 | uint32_t d;
30 | uint32_t e;
31 | uint32_t f;
32 | uint32_t g;
33 | uint32_t h;
34 | };
35 |
36 | @interface A : NSObject
37 | - (int) testI;
38 | - (dat) testS;
39 | @end
40 |
41 | @implementation A
42 |
43 | - (int) testI {
44 | return 0x31337;
45 | }
46 |
47 | - (dat) testS {
48 | dat value = { 0x31337 };
49 | return value;
50 | }
51 |
52 | @end
53 |
54 | @interface B : A
55 | @end
56 |
57 | @implementation B
58 | @end
59 |
60 | extern "C" bool MSDebug;
61 |
62 | struct Debug {
63 | Debug() {
64 | MSDebug = true;
65 | } } debug_;
66 |
67 | MSClassHook(B)
68 |
69 | MSInstanceMessageHook0(int, B, testI) {
70 | return MSOldCall() - 0x31337 + 0xae5bda7a;
71 | }
72 |
73 | MSInstanceMessageHook0(dat, B, testS) {
74 | dat value = { MSOldCall().a - 0x31337 + 0xae5bda7a };
75 | return value;
76 | }
77 |
78 | int main() {
79 | B *b([[B alloc] init]);
80 | printf("0x%x\n", [b testI]);
81 | printf("0x%x\n", [b testS].a);
82 | return 0;
83 | }
84 |
--------------------------------------------------------------------------------
/Trampoline.hpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #ifndef SUBSTRATE_TRAMPOLINE_HPP
23 | #define SUBSTRATE_TRAMPOLINE_HPP
24 |
25 | struct Trampoline {
26 | const char *data_;
27 | size_t size_;
28 | size_t entry_;
29 | };
30 |
31 | #endif//SUBSTRATE_TRAMPOLINE_HPP
32 |
--------------------------------------------------------------------------------
/Trampoline.t.cpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #include "DarwinThreadInternal.hpp"
23 |
24 | #include "Baton.hpp"
25 | #include "CydiaSubstrate.h"
26 |
27 | template
28 | static _finline void dlset(Baton *baton, Type_ &function, const char *name, void *handle = RTLD_DEFAULT) {
29 | function = reinterpret_cast(baton->dlsym(handle, name));
30 | if (function == NULL)
31 | baton->dlerror();
32 | }
33 |
34 | void *Routine(void *arg) {
35 | Baton *baton(reinterpret_cast(arg));
36 |
37 | void *(*dlopen)(const char *, int);
38 | dlset(baton, dlopen, "dlopen");
39 |
40 | void *handle(dlopen(baton->library, RTLD_LAZY | RTLD_LOCAL));
41 | if (handle == NULL) {
42 | baton->dlerror();
43 | return NULL;
44 | }
45 |
46 | int (*dlclose)(void *);
47 | dlset(baton, dlclose, "dlclose");
48 |
49 | dlclose(handle);
50 |
51 | return NULL;
52 | }
53 |
54 |
55 | // I am unable to link against any external functions, so reimplement bzero
56 | // XXX: there might be a gcc builtin for memset/bzero: use it instead?
57 |
58 | static void $bzero(void *data, size_t size) {
59 | char *bytes(reinterpret_cast(data));
60 | for (size_t i(0); i != size; ++i)
61 | bytes[i] = 0;
62 | }
63 |
64 |
65 | extern "C" void Start(Baton *baton) {
66 | // XXX: I am not certain if I should deallocate this port (an academic question, as I can't)
67 | mach_port_t port(baton->mach_thread_self());
68 |
69 | // normally, a pthread has a _pthread associated with it; pthread_t is a pointer to it
70 | // these are normally initialized by either _pthread_create or _pthread_struct_init
71 | // however, for our purposes, just initializing it to 0 is reasonably sufficient
72 | // XXX: look into using _pthread_create instead (_pthread_struct_init is often private)
73 |
74 | struct _pthread self;
75 | $bzero(&self, sizeof(self));
76 |
77 |
78 | // this code comes from _pthread_set_self, which is the startup routine of _pthread_body
79 | // XXX: __pthread_set_self seems to syscall thread_set_cthread... what does that do?
80 | // XXX: if we use _pthread_create/_pthread_struct_init, the tsd[0] will be handled
81 |
82 | self.tsd[0] = &self;
83 | baton->__pthread_set_self(&self);
84 |
85 |
86 | // on ARM, a coprocessor register has been allocated to keep track of a thread identifier
87 | // on iOS << 4.2, this register points at a pthread_t. the tsd table is at +0x48 offset
88 | // on iOS >= 4.2, this register points at the tsd table, with pthread_t at +0x00 offset
89 |
90 | // here, we need to detect whether the thread register is pointing at a valid table
91 | // otherwise, later code that attempts to use _pthread_setspecific_direct will crash
92 | // luckily, on iOS << 4.2, we also do not need to initialize thread local storage!
93 |
94 | bool setspecific;
95 | #ifdef __arm__
96 | void **tsd;
97 | __asm__ ("mrc p15, 0, %0, c13, c0, 3\n" : "=r"(tsd));
98 | setspecific = tsd != NULL;
99 | #else
100 | setspecific = true;
101 | #endif
102 |
103 |
104 | // the current thread identifier is stored in the 0th thread-specific data slot
105 | // thread-specific data, especially the 0th slot, is often stored in hardware registers
106 | // the _pthread_setspecific_direct macro allows us to update these static entries
107 | // we check setspecific, a variable defined above, to see whether this function works
108 |
109 | // note: it is not sufficient to set tsd[0] or to call _pthread_create/__pthread_set_self
110 | // even more interestingly, calling the full pthread_setspecific(0) doesn't even work
111 |
112 | if (setspecific)
113 | _pthread_setspecific_direct(0, &self);
114 |
115 |
116 | pthread_t thread;
117 | baton->pthread_create(&thread, NULL, &Routine, baton);
118 |
119 | void *status;
120 | baton->pthread_join(thread, &status);
121 |
122 | baton->thread_terminate(port);
123 | }
124 |
--------------------------------------------------------------------------------
/control:
--------------------------------------------------------------------------------
1 | Priority: optional
2 | Version:
3 | Description: powerful code insertion platform
4 | Maintainer: Jay Freeman (saurik)
5 | Section: System
6 |
--------------------------------------------------------------------------------
/control.arm:
--------------------------------------------------------------------------------
1 | Package: mobilesubstrate
2 | Architecture: iphoneos-arm
3 | Name: Mobile Substrate
4 | Author: Jay Freeman (saurik)
5 | Depiction: http://cydia.saurik.com/info/mobilesubstrate/
6 | Depends: com.saurik.substrate.safemode
7 | Breaks: uikittools (<< 1.1.1), com.mywi4 (<= 5.03.2), com.phoenix.pandoracontrols (<= 1.1.0-1), com.intelliborn.intelliscreenx (<= 1.0.110)
8 |
--------------------------------------------------------------------------------
/control.i386:
--------------------------------------------------------------------------------
1 | Package: com.cydia.substrate
2 | Architecture: cydia
3 | Depends: cy+cpu.arm | cy+cpu.i386, cy+os.macosx (>= 10.5) | cy+os.ios (>= 2.0), cy+os.macosx | com.saurik.substrate.safemode
4 | Cydia-Name: Cydia Substrate
5 | Cydia-Author: Jay Freeman (saurik)
6 | Cydia-Depiction: http://cydia.saurik.com/info/mobilesubstrate/
7 |
--------------------------------------------------------------------------------
/control.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | dir=$1
3 | dir=${dir:=_}
4 | sed -e "s@^\(Version:\).*@\1 $(./version.sh)@" control
5 | #echo "Installed-Size: $(du -s "${dir}" | cut -f 1)"
6 |
--------------------------------------------------------------------------------
/cynject.cpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #include "CydiaSubstrate.h"
23 |
24 | #include
25 |
26 | int main(int argc, const char *argv[]) {
27 | if (argc != 3) {
28 | fprintf(stderr, "usage: %s \n", argv[0]);
29 | return 1;
30 | }
31 |
32 | pid_t pid(strtoul(argv[1], NULL, 10));
33 | const char *library(argv[2]);
34 |
35 | if (!MSHookProcess(pid, library)) {
36 | fprintf(stderr, "MSHookProcess() failed.\n");
37 | return 1;
38 | }
39 |
40 | return 0;
41 | }
42 |
--------------------------------------------------------------------------------
/darwin.mk:
--------------------------------------------------------------------------------
1 | # Cydia Substrate - Powerful Code Insertion Platform
2 | # Copyright (C) 2008-2011 Jay Freeman (saurik)
3 |
4 | # GNU Lesser General Public License, Version 3 {{{
5 | #
6 | # Substrate is free software: you can redistribute it and/or modify it under
7 | # the terms of the GNU Lesser General Public License as published by the
8 | # Free Software Foundation, either version 3 of the License, or (at your
9 | # option) any later version.
10 | #
11 | # Substrate is distributed in the hope that it will be useful, but WITHOUT
12 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 | # License for more details.
15 | #
16 | # You should have received a copy of the GNU Lesser General Public License
17 | # along with Substrate. If not, see .
18 | # }}}
19 |
20 | ios := -i2.0
21 | mac := -m10.5
22 |
23 | flags :=
24 | flags += -O2 -g0
25 |
26 | flags += -isystem extra
27 | flags += -fno-exceptions
28 | flags += -fvisibility=hidden
29 |
30 | flags_Hooker := -Ihde64c/include
31 | flags_MachMessage := -Xarch_armv6 -marm
32 |
33 | hde64c := -Xarch_i386 hde64c/src/hde64.c -Xarch_x86_64 hde64c/src/hde64.c
34 | lsubstrate := Debug.o Hooker.o MachMemory.o MachMessage.o hde64c/src/hde64.c
35 |
36 | framework := /Library/Frameworks/CydiaSubstrate.framework
37 |
38 | cycc = ./cycc $(ios) $(mac) -o$@ -- $(flags) $(filter %.o,$^) $(filter %.dylib,$^)
39 |
40 | all: darwin
41 |
42 | darwin: libsubstrate.dylib SubstrateBootstrap.dylib SubstrateLauncher.dylib SubstrateLoader.dylib cynject
43 | ios: darwin
44 |
45 | %.t.hpp: %.t.cpp trampoline.sh
46 | ./trampoline.sh $@ $*.dylib $* sed otool lipo nm ./cycc $(ios) $(mac) -o$*.dylib -- -dynamiclib $< -Iinclude -Xarch_armv6 -marm
47 |
48 | MachProtect.c: MachProtect.defs MachInterface.sh
49 | ./MachInterface.sh $@ MachProtect.h $<
50 |
51 | MachMemory.o: MachProtect.c
52 | DarwinInjector.o: Trampoline.t.hpp
53 |
54 | %.o: %.cpp
55 | $(cycc) $(flags_$*) -c -Iinclude $<
56 |
57 | %.o: %.mm
58 | $(cycc) $(flags_$*) -c -Iinclude $<
59 |
60 | libsubstrate.dylib: DarwinFindSymbol.o DarwinInjector.o ObjectiveC.o $(lsubstrate)
61 | $(cycc) -dynamiclib $(hde64c) -lobjc -install_name $(framework)/CydiaSubstrate
62 |
63 | SubstrateBootstrap.dylib: Bootstrap.o
64 | $(cycc) -dynamiclib
65 |
66 | SubstrateLauncher.dylib: DarwinLauncher.o $(lsubstrate)
67 | $(cycc) -dynamiclib $(hde64c)
68 |
69 | SubstrateLoader.dylib: DarwinLoader.o Environment.o
70 | $(cycc) -dynamiclib -framework CoreFoundation
71 |
72 | cynject: cynject.o libsubstrate.dylib
73 | $(cycc)
74 | ldid -Stask_for_pid.xml $@
75 |
76 | %: %.o
77 | $(cycc) -framework CoreFoundation -framework Foundation
78 |
79 | extrainst_ postrm: LaunchDaemons.o Cydia.o
80 |
81 | deb: ios extrainst_ postrm
82 | ./package.sh i386
83 | ./package.sh arm
84 |
85 | package: deb
86 |
87 | install: deb
88 | PATH=/Library/Cydia/bin:/usr/sbin:/usr/bin:/sbin:/bin sudo dpkg -i com.cydia.substrate_$(shell ./version.sh)_cydia.deb
89 |
90 | upgrade: all
91 | sudo cp -a libsubstrate.dylib $(framework)/CydiaSubstrate
92 | sudo cp -a SubstrateBootstrap.dylib $(framework)/Libraries
93 | sudo cp -a SubstrateLauncher.dylib $(framework)/Libraries
94 | sudo cp -a SubstrateLoader.dylib $(framework)/Libraries
95 |
96 | clean:
97 | rm -f MachProtect.h MachProtect.c *.o libsubstrate.dylib SubstrateBootstrap.dylib SubstrateLauncher.dylib SubstrateLoader.dylib extrainst_ postrm cynject
98 |
99 | TestSuperCall: libsubstrate.dylib
100 |
101 | test: TestSuperCall
102 | arch -i386 ./TestSuperCall
103 | arch -x86_64 ./TestSuperCall
104 |
105 | .PHONY: all clean darwin deb install ios test package upgrade
106 |
--------------------------------------------------------------------------------
/extra/CoreFoundation/CFBundlePriv.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2008 Apple Inc. All rights reserved.
3 | *
4 | * @APPLE_LICENSE_HEADER_START@
5 | *
6 | * This file contains Original Code and/or Modifications of Original Code
7 | * as defined in and that are subject to the Apple Public Source License
8 | * Version 2.0 (the 'License'). You may not use this file except in
9 | * compliance with the License. Please obtain a copy of the License at
10 | * http://www.opensource.apple.com/apsl/ and read it before using this
11 | * file.
12 | *
13 | * The Original Code and all software distributed under the License are
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 | * Please see the License for the specific language governing rights and
19 | * limitations under the License.
20 | *
21 | * @APPLE_LICENSE_HEADER_END@
22 | */
23 | /* CFBundlePriv.h
24 | Copyright (c) 1999-2007, Apple Inc. All rights reserved.
25 | */
26 |
27 | #if !defined(__COREFOUNDATION_CFBUNDLEPRIV__)
28 | #define __COREFOUNDATION_CFBUNDLEPRIV__ 1
29 |
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 |
37 | CF_EXTERN_C_BEGIN
38 |
39 | /* Finder stuff */
40 | CF_EXPORT
41 | const CFStringRef _kCFBundlePackageTypeKey;
42 | CF_EXPORT
43 | const CFStringRef _kCFBundleSignatureKey;
44 | CF_EXPORT
45 | const CFStringRef _kCFBundleIconFileKey;
46 | CF_EXPORT
47 | const CFStringRef _kCFBundleDocumentTypesKey;
48 | CF_EXPORT
49 | const CFStringRef _kCFBundleURLTypesKey;
50 |
51 | /* Localizable Finder stuff */
52 | CF_EXPORT
53 | const CFStringRef _kCFBundleDisplayNameKey;
54 | CF_EXPORT
55 | const CFStringRef _kCFBundleShortVersionStringKey;
56 | CF_EXPORT
57 | const CFStringRef _kCFBundleGetInfoStringKey;
58 | CF_EXPORT
59 | const CFStringRef _kCFBundleGetInfoHTMLKey;
60 |
61 | /* Sub-keys for CFBundleDocumentTypes dictionaries */
62 | CF_EXPORT
63 | const CFStringRef _kCFBundleTypeNameKey;
64 | CF_EXPORT
65 | const CFStringRef _kCFBundleTypeRoleKey;
66 | CF_EXPORT
67 | const CFStringRef _kCFBundleTypeIconFileKey;
68 | CF_EXPORT
69 | const CFStringRef _kCFBundleTypeOSTypesKey;
70 | CF_EXPORT
71 | const CFStringRef _kCFBundleTypeExtensionsKey;
72 | CF_EXPORT
73 | const CFStringRef _kCFBundleTypeMIMETypesKey;
74 |
75 | /* Sub-keys for CFBundleURLTypes dictionaries */
76 | CF_EXPORT
77 | const CFStringRef _kCFBundleURLNameKey;
78 | CF_EXPORT
79 | const CFStringRef _kCFBundleURLIconFileKey;
80 | CF_EXPORT
81 | const CFStringRef _kCFBundleURLSchemesKey;
82 |
83 | /* Compatibility key names */
84 | CF_EXPORT
85 | const CFStringRef _kCFBundleOldExecutableKey;
86 | CF_EXPORT
87 | const CFStringRef _kCFBundleOldInfoDictionaryVersionKey;
88 | CF_EXPORT
89 | const CFStringRef _kCFBundleOldNameKey;
90 | CF_EXPORT
91 | const CFStringRef _kCFBundleOldIconFileKey;
92 | CF_EXPORT
93 | const CFStringRef _kCFBundleOldDocumentTypesKey;
94 | CF_EXPORT
95 | const CFStringRef _kCFBundleOldShortVersionStringKey;
96 |
97 | /* Compatibility CFBundleDocumentTypes key names */
98 | CF_EXPORT
99 | const CFStringRef _kCFBundleOldTypeNameKey;
100 | CF_EXPORT
101 | const CFStringRef _kCFBundleOldTypeRoleKey;
102 | CF_EXPORT
103 | const CFStringRef _kCFBundleOldTypeIconFileKey;
104 | CF_EXPORT
105 | const CFStringRef _kCFBundleOldTypeExtensions1Key;
106 | CF_EXPORT
107 | const CFStringRef _kCFBundleOldTypeExtensions2Key;
108 | CF_EXPORT
109 | const CFStringRef _kCFBundleOldTypeOSTypesKey;
110 |
111 |
112 | /* Functions for examining directories that may "look like" bundles */
113 |
114 | CF_EXPORT
115 | CFURLRef _CFBundleCopyBundleURLForExecutableURL(CFURLRef url);
116 |
117 | CF_EXPORT
118 | Boolean _CFBundleURLLooksLikeBundle(CFURLRef url);
119 |
120 | CF_EXPORT
121 | CFBundleRef _CFBundleCreateIfLooksLikeBundle(CFAllocatorRef allocator, CFURLRef url);
122 |
123 | CF_EXPORT
124 | CFBundleRef _CFBundleGetMainBundleIfLooksLikeBundle(void);
125 |
126 | CF_EXPORT
127 | Boolean _CFBundleMainBundleInfoDictionaryComesFromResourceFork(void);
128 |
129 | CF_EXPORT
130 | CFBundleRef _CFBundleCreateWithExecutableURLIfLooksLikeBundle(CFAllocatorRef allocator, CFURLRef url);
131 |
132 | CF_EXPORT
133 | CFURLRef _CFBundleCopyMainBundleExecutableURL(Boolean *looksLikeBundle);
134 |
135 | CF_EXPORT
136 | CFBundleRef _CFBundleGetExistingBundleWithBundleURL(CFURLRef bundleURL);
137 |
138 | /* Functions for examining the structure of a bundle */
139 |
140 | CF_EXPORT
141 | CFURLRef _CFBundleCopyResourceForkURL(CFBundleRef bundle);
142 |
143 | CF_EXPORT
144 | CFURLRef _CFBundleCopyInfoPlistURL(CFBundleRef bundle);
145 |
146 |
147 | /* Functions for working without a bundle instance */
148 |
149 | CF_EXPORT
150 | CFURLRef _CFBundleCopyExecutableURLInDirectory(CFURLRef url);
151 |
152 | CF_EXPORT
153 | CFURLRef _CFBundleCopyOtherExecutableURLInDirectory(CFURLRef url);
154 |
155 |
156 | /* Functions for dealing with localizations */
157 |
158 | CF_EXPORT
159 | void _CFBundleGetLanguageAndRegionCodes(SInt32 *languageCode, SInt32 *regionCode);
160 | // may return -1 for either one if no code can be found
161 |
162 | CF_EXPORT
163 | Boolean CFBundleGetLocalizationInfoForLocalization(CFStringRef localizationName, SInt32 *languageCode, SInt32 *regionCode, SInt32 *scriptCode, CFStringEncoding *stringEncoding);
164 | /* Gets the appropriate language and region codes, and the default */
165 | /* script code and encoding, for the localization specified. */
166 | /* Pass NULL for the localizationName to get these values for the */
167 | /* single most preferred localization in the current context. */
168 | /* May give -1 if there is no language or region code for a particular */
169 | /* localization. Returns false if CFBundle has no information about */
170 | /* the given localization. */
171 |
172 | CF_EXPORT
173 | CFStringRef CFBundleCopyLocalizationForLocalizationInfo(SInt32 languageCode, SInt32 regionCode, SInt32 scriptCode, CFStringEncoding stringEncoding);
174 | /* Returns the default localization for the combination of codes */
175 | /* specified. Pass in -1 for language, region code, or script code, or */
176 | /* 0xFFFF for stringEncoding, if you do not wish to specify one of these. */
177 |
178 | CF_EXPORT
179 | void _CFBundleSetDefaultLocalization(CFStringRef localizationName);
180 |
181 |
182 | /* Functions for dealing specifically with CFM executables */
183 |
184 | CF_EXPORT
185 | void *_CFBundleGetCFMFunctionPointerForName(CFBundleRef bundle, CFStringRef funcName);
186 |
187 | CF_EXPORT
188 | void _CFBundleGetCFMFunctionPointersForNames(CFBundleRef bundle, CFArrayRef functionNames, void *ftbl[]);
189 |
190 | CF_EXPORT
191 | void _CFBundleSetCFMConnectionID(CFBundleRef bundle, void *connectionID);
192 |
193 |
194 | /* Miscellaneous functions */
195 |
196 | CF_EXPORT
197 | CFStringRef _CFBundleCopyFileTypeForFileURL(CFURLRef url);
198 |
199 | CF_EXPORT
200 | CFStringRef _CFBundleCopyFileTypeForFileData(CFDataRef data);
201 |
202 | CF_EXPORT
203 | Boolean _CFBundleGetHasChanged(CFBundleRef bundle);
204 |
205 | CF_EXPORT
206 | void _CFBundleFlushCaches(void);
207 |
208 | CF_EXPORT
209 | void _CFBundleFlushCachesForURL(CFURLRef url);
210 |
211 | CF_EXPORT
212 | void _CFBundleFlushBundleCaches(CFBundleRef bundle); // The previous two functions flush cached resource paths; this one also flushes bundle-specific caches such as the info dictionary and strings files
213 |
214 | CF_EXPORT
215 | void _CFBundleSetStringsFilesShared(CFBundleRef bundle, Boolean flag);
216 |
217 | CF_EXPORT
218 | Boolean _CFBundleGetStringsFilesShared(CFBundleRef bundle);
219 |
220 |
221 | /* Functions deprecated as SPI */
222 |
223 | CF_EXPORT
224 | CFDictionaryRef _CFBundleGetLocalInfoDictionary(CFBundleRef bundle); // deprecated in favor of CFBundleGetLocalInfoDictionary
225 |
226 | CF_EXPORT
227 | CFPropertyListRef _CFBundleGetValueForInfoKey(CFBundleRef bundle, CFStringRef key); // deprecated in favor of CFBundleGetValueForInfoDictionaryKey
228 |
229 | CF_EXPORT
230 | Boolean _CFBundleGetPackageInfoInDirectory(CFAllocatorRef alloc, CFURLRef url, UInt32 *packageType, UInt32 *packageCreator); // deprecated in favor of CFBundleGetPackageInfoInDirectory
231 |
232 | CF_EXPORT
233 | CFDictionaryRef _CFBundleCopyInfoDictionaryInResourceFork(CFURLRef url); // CFBundleCopyInfoDictionaryForURL is usually preferred; for the main bundle, however, no special call is necessary, since the info dictionary will automatically be available whether the app is bundled or not
234 |
235 | CF_EXPORT
236 | CFURLRef _CFBundleCopyPrivateFrameworksURL(CFBundleRef bundle); // deprecated in favor of CFBundleCopyPrivateFrameworksURL
237 |
238 | CF_EXPORT
239 | CFURLRef _CFBundleCopySharedFrameworksURL(CFBundleRef bundle); // deprecated in favor of CFBundleCopySharedFrameworksURL
240 |
241 | CF_EXPORT
242 | CFURLRef _CFBundleCopySharedSupportURL(CFBundleRef bundle); // deprecated in favor of CFBundleCopySharedSupportURL
243 |
244 | CF_EXPORT
245 | CFURLRef _CFBundleCopyBuiltInPlugInsURL(CFBundleRef bundle); // deprecated in favor of CFBundleCopyBuiltInPlugInsURL
246 |
247 | CF_EXPORT
248 | CFArrayRef _CFBundleCopyBundleRegionsArray(CFBundleRef bundle); // deprecated in favor of CFBundleCopyBundleLocalizations
249 |
250 | CF_EXPORT
251 | CFURLRef _CFBundleCopyResourceURLForLanguage(CFBundleRef bundle, CFStringRef resourceName, CFStringRef resourceType, CFStringRef subDirName, CFStringRef language); // deprecated in favor of CFBundleCopyResourceURLForLocalization
252 |
253 | CF_EXPORT
254 | CFArrayRef _CFBundleCopyResourceURLsOfTypeForLanguage(CFBundleRef bundle, CFStringRef resourceType, CFStringRef subDirName, CFStringRef language); // deprecated in favor of CFBundleCopyResourceURLsOfTypeForLocalization
255 |
256 | CF_EXPORT
257 | CFBundleRefNum _CFBundleOpenBundleResourceFork(CFBundleRef bundle); // deprecated in favor of CFBundleOpenBundleResourceMap
258 |
259 | CF_EXPORT
260 | void _CFBundleCloseBundleResourceFork(CFBundleRef bundle); // deprecated in favor of CFBundleCloseBundleResourceMap
261 |
262 | CF_EXTERN_C_END
263 |
264 | #endif /* ! __COREFOUNDATION_CFBUNDLEPRIV__ */
265 |
266 |
--------------------------------------------------------------------------------
/extra/CoreFoundation/CFLogUtilities.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2008 Apple Inc. All rights reserved.
3 | *
4 | * @APPLE_LICENSE_HEADER_START@
5 | *
6 | * This file contains Original Code and/or Modifications of Original Code
7 | * as defined in and that are subject to the Apple Public Source License
8 | * Version 2.0 (the 'License'). You may not use this file except in
9 | * compliance with the License. Please obtain a copy of the License at
10 | * http://www.opensource.apple.com/apsl/ and read it before using this
11 | * file.
12 | *
13 | * The Original Code and all software distributed under the License are
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 | * Please see the License for the specific language governing rights and
19 | * limitations under the License.
20 | *
21 | * @APPLE_LICENSE_HEADER_END@
22 | */
23 | /* CFLogUtilities.h
24 | Copyright (c) 2004-2007, Apple Inc. All rights reserved.
25 | */
26 |
27 | /*
28 | APPLE SPI: NOT TO BE USED OUTSIDE APPLE!
29 | */
30 |
31 | #if !defined(__COREFOUNDATION_CFLOGUTILITIES__)
32 | #define __COREFOUNDATION_CFLOGUTILITIES__ 1
33 |
34 | #include
35 | #include
36 |
37 | CF_EXTERN_C_BEGIN
38 |
39 |
40 | enum { // Legal level values for CFLog()
41 | kCFLogLevelEmergency = 0,
42 | kCFLogLevelAlert = 1,
43 | kCFLogLevelCritical = 2,
44 | kCFLogLevelError = 3,
45 | kCFLogLevelWarning = 4,
46 | kCFLogLevelNotice = 5,
47 | kCFLogLevelInfo = 6,
48 | kCFLogLevelDebug = 7,
49 | };
50 |
51 | CF_EXPORT void CFLog(int32_t level, CFStringRef format, ...);
52 | /* Passing in a level value which is outside the range of 0-7 will cause the the call to do nothing.
53 | CFLog() logs the message using the asl.h API, and uses the level parameter as the log level.
54 | Note that the asl subsystem ignores some log levels by default.
55 | CFLog() is not fast, and is not going to be guaranteed to be fast.
56 | Even "no-op" CFLogs are not necessarily fast.
57 | If you care about performance, you shouldn't be logging.
58 | */
59 |
60 | CF_EXTERN_C_END
61 |
62 | #endif /* ! __COREFOUNDATION_CFLOGUTILITIES__ */
63 |
64 |
--------------------------------------------------------------------------------
/extra/machine/exec.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
3 | *
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 | *
6 | * This file contains Original Code and/or Modifications of Original Code
7 | * as defined in and that are subject to the Apple Public Source License
8 | * Version 2.0 (the 'License'). You may not use this file except in
9 | * compliance with the License. The rights granted to you under the License
10 | * may not be used to create, or enable the creation or redistribution of,
11 | * unlawful or unlicensed copies of an Apple operating system, or to
12 | * circumvent, violate, or enable the circumvention or violation of, any
13 | * terms of an Apple operating system software license agreement.
14 | *
15 | * Please obtain a copy of the License at
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 | *
18 | * The Original Code and all software distributed under the License are
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 | * Please see the License for the specific language governing rights and
24 | * limitations under the License.
25 | *
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 | */
28 | /*-
29 | * Copyright (c) 1992, 1993
30 | * The Regents of the University of California. All rights reserved.
31 | *
32 | * Redistribution and use in source and binary forms, with or without
33 | * modification, are permitted provided that the following conditions
34 | * are met:
35 | * 1. Redistributions of source code must retain the above copyright
36 | * notice, this list of conditions and the following disclaimer.
37 | * 2. Redistributions in binary form must reproduce the above copyright
38 | * notice, this list of conditions and the following disclaimer in the
39 | * documentation and/or other materials provided with the distribution.
40 | * 3. All advertising materials mentioning features or use of this software
41 | * must display the following acknowledgement:
42 | * This product includes software developed by the University of
43 | * California, Berkeley and its contributors.
44 | * 4. Neither the name of the University nor the names of its contributors
45 | * may be used to endorse or promote products derived from this software
46 | * without specific prior written permission.
47 | *
48 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 | * SUCH DAMAGE.
59 | *
60 | * @(#)exec.h 8.1 (Berkeley) 6/11/93
61 | */
62 |
63 | #ifndef _BSD_I386_EXEC_H_
64 | #define _BSD_I386_EXEC_H_
65 |
66 |
67 | #ifdef BSD_KERNEL_PRIVATE
68 | /* Size of a page in an object file. */
69 | #define __LDPGSZ 4096
70 |
71 | /* Valid magic number check. */
72 | #define N_BADMAG(ex) \
73 | ((ex).a_magic != NMAGIC && (ex).a_magic != OMAGIC && \
74 | (ex).a_magic != ZMAGIC)
75 |
76 | /* Address of the bottom of the text segment. */
77 | #define N_TXTADDR(X) 0
78 |
79 | /* Address of the bottom of the data segment. */
80 | #define N_DATADDR(ex) \
81 | (N_TXTADDR(ex) + ((ex).a_magic == OMAGIC ? (ex).a_text \
82 | : __LDPGSZ + ((ex).a_text - 1 & ~(__LDPGSZ - 1))))
83 |
84 | /* Text segment offset. */
85 | #define N_TXTOFF(ex) \
86 | ((ex).a_magic == ZMAGIC ? __LDPGSZ : sizeof(struct exec))
87 |
88 | /* Data segment offset. */
89 | #define N_DATOFF(ex) \
90 | (N_TXTOFF(ex) + ((ex).a_magic != ZMAGIC ? (ex).a_text : \
91 | __LDPGSZ + ((ex).a_text - 1 & ~(__LDPGSZ - 1))))
92 |
93 | /* Symbol table offset. */
94 | #define N_SYMOFF(ex) \
95 | (N_TXTOFF(ex) + (ex).a_text + (ex).a_data + (ex).a_trsize + \
96 | (ex).a_drsize)
97 |
98 | /* String table offset. */
99 | #define N_STROFF(ex) (N_SYMOFF(ex) + (ex).a_syms)
100 |
101 | /* Description of the object file header (a.out format). */
102 | struct exec {
103 | #define OMAGIC 0407 /* old impure format */
104 | #define NMAGIC 0410 /* read-only text */
105 | #define ZMAGIC 0413 /* demand load format */
106 | #define QMAGIC 0314 /* demand load format. Header in text. */
107 | unsigned int a_magic; /* magic number */
108 |
109 | unsigned int a_text; /* text segment size */
110 | unsigned int a_data; /* initialized data size */
111 | unsigned int a_bss; /* uninitialized data size */
112 | unsigned int a_syms; /* symbol table size */
113 | unsigned int a_entry; /* entry point */
114 | unsigned int a_trsize; /* text relocation size */
115 | unsigned int a_drsize; /* data relocation size */
116 | };
117 |
118 | #endif /* BSD_KERNEL_PRIVATE */
119 |
120 | #endif /* _BSD_I386_EXEC_H_ */
121 |
--------------------------------------------------------------------------------
/extrainst_.mm:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #include
23 | #import
24 | #include
25 | #include
26 |
27 | #include "Cydia.hpp"
28 | #include "Environment.hpp"
29 | #include "LaunchDaemons.hpp"
30 |
31 | #ifdef __arm__
32 |
33 | // XXX: NO means "failed", false means "unneeded"
34 |
35 | static bool HookEnvironment(const char *name) {
36 | NSString *file([NSString stringWithFormat:@"%@/%s.plist", @ SubstrateLaunchDaemons_, name]);
37 | if (file == nil)
38 | return NO;
39 |
40 | NSMutableDictionary *root([NSMutableDictionary dictionaryWithContentsOfFile:file]);
41 | if (root == nil)
42 | return NO;
43 |
44 | NSMutableDictionary *environment([root objectForKey:@"EnvironmentVariables"]);
45 | if (environment == nil) {
46 | environment = [NSMutableDictionary dictionaryWithCapacity:1];
47 | if (environment == nil)
48 | return NO;
49 |
50 | [root setObject:environment forKey:@"EnvironmentVariables"];
51 | }
52 |
53 | NSString *variable([environment objectForKey:@ SubstrateVariable_]);
54 | if (variable == nil || [variable length] == 0)
55 | [environment setObject:@ SubstrateLibrary_ forKey:@ SubstrateVariable_];
56 | else {
57 | NSArray *dylibs([variable componentsSeparatedByString:@":"]);
58 | if (dylibs == nil)
59 | return NO;
60 |
61 | NSUInteger index([dylibs indexOfObject:@ SubstrateLibrary_]);
62 | if (index != NSNotFound)
63 | return false;
64 |
65 | [environment setObject:[NSString stringWithFormat:@"%@:%@", variable, @ SubstrateLibrary_] forKey:@ SubstrateVariable_];
66 | }
67 |
68 | NSString *error;
69 | NSData *data([NSPropertyListSerialization dataFromPropertyList:root format:NSPropertyListBinaryFormat_v1_0 errorDescription:&error]);
70 | if (data == nil)
71 | return NO;
72 |
73 | if (![data writeToFile:file atomically:YES])
74 | return NO;
75 |
76 | return true;
77 | }
78 |
79 | static int InstallTether() {
80 | HookEnvironment("com.apple.mediaserverd");
81 | HookEnvironment("com.apple.itunesstored");
82 | HookEnvironment("com.apple.CommCenter");
83 | HookEnvironment("com.apple.AOSNotification");
84 |
85 | HookEnvironment("com.apple.BTServer");
86 | HookEnvironment("com.apple.iapd");
87 |
88 | HookEnvironment("com.apple.lsd");
89 | HookEnvironment("com.apple.imagent");
90 |
91 | HookEnvironment("com.apple.mobile.lockdown");
92 | HookEnvironment("com.apple.itdbprep.server");
93 |
94 | HookEnvironment("com.apple.locationd");
95 |
96 | HookEnvironment("com.apple.mediaremoted");
97 | HookEnvironment("com.apple.frontrow");
98 |
99 | HookEnvironment("com.apple.voiced");
100 | HookEnvironment("com.apple.MobileInternetSharing");
101 |
102 | HookEnvironment("com.apple.CommCenterClassic");
103 | HookEnvironment("com.apple.gamed");
104 |
105 | HookEnvironment("com.apple.mobile.softwareupdated");
106 | HookEnvironment("com.apple.softwareupdateservicesd");
107 | HookEnvironment("com.apple.twitterd");
108 | HookEnvironment("com.apple.mediaremoted");
109 |
110 | HookEnvironment("com.apple.assistivetouchd");
111 | HookEnvironment("com.apple.accountsd");
112 |
113 | HookEnvironment("com.apple.configd");
114 | HookEnvironment("com.apple.wifid");
115 | HookEnvironment("com.apple.mobile.installd");
116 |
117 | HookEnvironment("com.apple.SpringBoard");
118 |
119 | FinishCydia("reboot");
120 |
121 | return 0;
122 | }
123 |
124 | #endif
125 |
126 | static int InstallSemiTether() {
127 | MSClearLaunchDaemons();
128 |
129 | NSFileManager *manager([NSFileManager defaultManager]);
130 | NSError *error;
131 |
132 |
133 | // we must copy the dylib to a new filename in order to guarantee that dlopen() considers it to be different
134 | // if we fail to do this, it is quite unfortunate, but often it will work to use the original name
135 |
136 | NSString *temp([NSString stringWithFormat:@"/tmp/ms-%f.dylib", [[NSDate date] timeIntervalSinceReferenceDate]]);
137 |
138 | NSString *dylib;
139 | if ([manager copyItemAtPath:@ SubstrateLauncher_ toPath:temp error:&error])
140 | dylib = temp;
141 | else {
142 | fprintf(stderr, "unable to copy: %s\n", [[error description] UTF8String]);
143 | // XXX: this is not actually reasonable
144 | dylib = @ SubstrateLauncher_;
145 | temp = nil;
146 | }
147 |
148 |
149 | // XXX: check the result code and do something about failures
150 | system([[@"/usr/bin/cynject 1 " stringByAppendingString:dylib] UTF8String]);
151 |
152 |
153 | // if we are unable to remove the file copied into /tmp, it is interesting, but harmless
154 |
155 | if (temp != nil && ![manager removeItemAtPath:temp error:&error])
156 | if (unlink([temp UTF8String]) == -1)
157 | fprintf(stderr, "unable to remove: (%s):%d\n", [[error description] UTF8String], errno);
158 |
159 |
160 | NSString *config([NSString stringWithContentsOfFile:@ SubstrateLaunchConfig_ encoding:NSNonLossyASCIIStringEncoding error:&error]);
161 | // XXX: if the file fails to load, it might not be missing: it might be unreadable for some reason
162 | if (config == nil)
163 | config = @"";
164 |
165 | NSArray *lines([config componentsSeparatedByString:@"\n"]);
166 | NSMutableArray *copy([lines mutableCopy]);
167 |
168 | [copy removeObject:@""];
169 |
170 | if ([lines indexOfObject:@ SubstrateBootstrapExecute_] == NSNotFound)
171 | [copy addObject:@ SubstrateBootstrapExecute_];
172 |
173 | [copy addObject:@""];
174 |
175 | if (![copy isEqualToArray:lines])
176 | [[copy componentsJoinedByString:@"\n"] writeToFile:@ SubstrateLaunchConfig_ atomically:YES encoding:NSNonLossyASCIIStringEncoding error:&error];
177 |
178 | return 0;
179 | }
180 |
181 | #ifdef __arm__
182 |
183 | static int InstallQuasiTether() {
184 | // JailbreakMe 3.0 "Saffron" bootstrapped itself using /usr/libexec/dirhelper
185 | // unfortunately, dirhelper is run too long after launchd.conf is processed
186 | // here we detect whether dirhelper is /boot/untether so as to install tethered
187 |
188 | // further, Saffron used a special filesystem called "unionfs" instead of stashing
189 | // this prevents us from easily being able to make modifications to the injector
190 | // it should be noted that we cannot use launchd.conf itself, also due to unionfs
191 |
192 | // luckily, comex implemented rename() to work on files in situ (under the mount)
193 | // however, most of the programs we can execute from launchctl require /bin/sh
194 | // the two that do not: rc.boot (before fstab mount), cc_fips_test (not on 4.3)
195 | // so, we really don't have any good options to fix this: we need to mark it buggy
196 |
197 | // XXX: the one remaining option is to unmount /etc, modify injection, and remount
198 |
199 | char dirhelper[1024];
200 | memset(dirhelper, 0, sizeof(dirhelper));
201 |
202 | // we use sizeof(dirhelper) - 1, as readlink() does not NUL-terminate the buffer
203 |
204 | if (readlink("/usr/libexec/dirhelper", dirhelper, sizeof(dirhelper) - 1) > 0)
205 | if (strcmp(dirhelper, "/boot/untether") == 0)
206 | return InstallTether();
207 |
208 |
209 | // there is a horrible bug in some jailbreaks where fork() causes dirty pages to become codesign invalid
210 | // as our posix_spawn hook in launchd occurs after a call to fork(), we cannot use that injection mechanism
211 |
212 | switch (DetectForkBug()) {
213 | case ForkBugUnknown:
214 | return 1;
215 |
216 | case ForkBugPresent:
217 | return InstallTether();
218 |
219 | case ForkBugMissing:
220 | break;
221 | }
222 |
223 | return InstallSemiTether();
224 | }
225 |
226 | #endif
227 |
228 | int main(int argc, char *argv[]) {
229 | if (argc < 2 || (
230 | strcmp(argv[1], "install") != 0 &&
231 | strcmp(argv[1], "upgrade") != 0 &&
232 | true)) return 0;
233 |
234 | NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
235 |
236 | #ifdef __arm__
237 | int result(InstallQuasiTether());
238 | #else
239 | int result(InstallSemiTether());
240 | #endif
241 |
242 | [pool release];
243 |
244 | // XXX: in general, this return 0 happens way too often
245 | return result;
246 | }
247 |
--------------------------------------------------------------------------------
/hde64c/LICENSE:
--------------------------------------------------------------------------------
1 | License agreement
2 |
3 | Hacker Disassembler Engine 64 C
4 | Copyright (c) 2008-2009, Vyacheslav Patkov.
5 | All rights reserved.
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions
9 | are met:
10 |
11 | 1. Redistributions of source code must retain the above copyright
12 | notice, this list of conditions and the following disclaimer.
13 | 2. Redistributions in binary form must reproduce the above copyright
14 | notice, this list of conditions and the following disclaimer in the
15 | documentation and/or other materials provided with the distribution.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/hde64c/NEWS:
--------------------------------------------------------------------------------
1 |
2 | My english is bad, I hope that you understand me ;)
3 |
4 |
5 | version 0.04 [2009.03.09] FINAL
6 | + now relative addresses stored to hde64s.imm* (see doc/ for more info)
7 | + removed first sentence from LICENSE
8 |
9 | version 0.03 [2009.01.02]
10 | + fixed bug: error setting 0x800000 flag to "hde64s.flags" when no prefixes
11 |
12 | version 0.02 [2008.11.02]
13 | + associated some fields of "hde64s" structure into unions
14 | + repacked table, it redecued on 37 bytes
15 |
16 | version 0.01 [2008.09.22]
17 | + first release
18 |
--------------------------------------------------------------------------------
/hde64c/THANKS:
--------------------------------------------------------------------------------
1 | HDE64 would not be what it is today without the invaluable help of:
2 |
3 | IceStudent
4 | herm1t
5 | Christian Ludloff
6 | Intel Corporation
7 |
--------------------------------------------------------------------------------
/hde64c/doc/en/manual.txt:
--------------------------------------------------------------------------------
1 |
2 | Hacker Disassembler Engine 64 C 0.04 FINAL
3 | ==========================================
4 |
5 | 1. What is it?
6 | 2. How to use?
7 | 3. Invalid instructions
8 | 4. Contacts
9 |
10 | My english is bad, I hope that you understand me ;) If you can translate the
11 | russian documentation, email me, please :)
12 |
13 | 1. What is it?
14 | ==============
15 |
16 | HDE64C is a small disassembler engine, intended for analysis of x86-64 code. It
17 | gets information about instruction (length, prefixes, opcode, ModR/M, SIB,..)
18 | and also detects invalid instructions. You can use the engine, for example,
19 | when working with executables, writing viruses, because most disassemblers too
20 | get only assembler mnemonic and aren't intended for analysis of code, but
21 | most simple length disassemblers get too little info. HDE64C gets enough info
22 | for analysis, but it has very small size.
23 |
24 | + support General-Purpose, FPU, MMX, SSE-SSE3, 3DNow! instructions
25 | + high-speed and small size (~ 2.5 kb)
26 | + operating system independent code
27 |
28 | 2. How to use?
29 | ==============
30 |
31 | To disassemble instruction should call "hde64_disasm" function. First argument
32 | is pointer to code, second - pointer to "hde64s" structure:
33 |
34 | unsigned int hde64_disasm(const void *code, hde64s *hs);
35 |
36 | You should follow C convention of arguments passing. The function returns
37 | length of the instruction and fill "hde64s" structure:
38 |
39 | typedef struct {
40 | uint8_t len; // length of command
41 | uint8_t p_rep; // rep/repz (0xf3) & repnz (0xf2) prefix
42 | uint8_t p_lock; // lock prefix: 0xf0
43 | uint8_t p_seg; // segment prefix: 0x26,0x2e,0x36,0x3e,0x64,0x65
44 | uint8_t p_66; // operand-size override prefix: 0x66
45 | uint8_t p_67; // address-size override prefix: 0x67
46 | uint8_t rex; // REX prefix
47 | uint8_t rex_w; // REX.W
48 | uint8_t rex_r; // REX.R
49 | uint8_t rex_x; // REX.X
50 | uint8_t rex_b; // REX.B
51 | uint8_t opcode; // opcode
52 | uint8_t opcode2; // second opcode (if first opcode is 0x0f)
53 | uint8_t modrm; // ModR/M byte
54 | uint8_t modrm_mod; // ModR/M.mod
55 | uint8_t modrm_reg; // ModR/M.reg
56 | uint8_t modrm_rm; // ModR/M.r/m
57 | uint8_t sib; // SIB byte
58 | uint8_t sib_scale; // SIB.scale
59 | uint8_t sib_index; // SIB.index
60 | uint8_t sib_base; // SIB.base
61 | union {
62 | uint8_t imm8; // immediate value imm8
63 | uint16_t imm16; // immediate value imm16
64 | uint32_t imm32; // immediate value imm32
65 | uint64_t imm64; // immediate value imm64
66 | } imm;
67 | union {
68 | uint8_t disp8; // displacement disp8
69 | uint16_t disp16; // displacement disp16
70 | uint32_t disp32; // displacement disp32
71 | } disp;
72 | uint32_t flags; // flags
73 | } hde64s;
74 |
75 | Special cases of immediate values are relative addresses. In previous versions
76 | of the engine this values stores to hde32s.rel* fields. But now it stored to
77 | hde32s.imm* as all others immediates. You can detect relative address by flag
78 | F_RELATIVE, which setted with one of F_IMM* flags (see below).
79 |
80 | Alignment of structure "hde64s" is 1 byte (no alignment). Be careful, check
81 | settings of your compiler or use headers from this package.
82 |
83 | Fields "hde64s.opcode" and "hde64s.len" will be always. Presence of other
84 | fields you can get with following flags in field "hde64s.flags":
85 |
86 | #define F_MODRM 0x00000001 // ModR/M exists
87 | #define F_SIB 0x00000002 // SIB exists
88 | #define F_IMM8 0x00000004 // immediate value imm8 exists
89 | #define F_IMM16 0x00000008 // immediate value imm16 exists
90 | #define F_IMM32 0x00000010 // immediate value imm32 exists
91 | #define F_IMM64 0x00000020 // immediate value imm64 exists
92 | #define F_DISP8 0x00000040 // displacement disp8 exists
93 | #define F_DISP16 0x00000080 // displacement disp16 exists
94 | #define F_DISP32 0x00000100 // displacement disp32 exists
95 | #define F_RELATIVE 0x00000200 // relative address rel8 exists
96 | #define F_PREFIX_REPNZ 0x01000000 // repnz prefix exists
97 | #define F_PREFIX_REPX 0x02000000 // rep(z) prefix exists
98 | #define F_PREFIX_REP 0x03000000 // rep(z) or repnz prefix exists
99 | #define F_PREFIX_66 0x04000000 // 0x66 prefix exists
100 | #define F_PREFIX_67 0x08000000 // 0x67 prefix exists
101 | #define F_PREFIX_LOCK 0x10000000 // lock prefix exists
102 | #define F_PREFIX_SEG 0x20000000 // segment prefix exists
103 | #define F_PREFIX_REX 0x40000000 // REX prefix exists
104 | #define F_PREFIX_ANY 0x7f000000 // any prefix esists
105 |
106 | HDE64C guaranteed that it read from "const void *code" no more than 26 bytes,
107 | if instruction is valid, than HDE64C read no more than "hde64s.len" bytes and
108 | "hde64s.len" always no more than 15.
109 |
110 | 3. Invalid instructions
111 | =======================
112 |
113 | HDE64C analyses instruction for invalid, and do it thoroughly (more than half
114 | of the size of engine is code and tables for detecting invalid instructions).
115 | If HDE64C think, that instruction is invalid, it set flag "F_ERROR":
116 |
117 | #define F_ERROR 0x00001000 // invalid instruction
118 |
119 | Besides, HDE64C set flags to explain type of error:
120 |
121 | #define F_ERROR_OPCODE 0x00002000 // invalid opcode
122 | #define F_ERROR_LENGTH 0x00004000 // length of command more than 15
123 | #define F_ERROR_LOCK 0x00008000 // prefix lock isn't allowed
124 | #define F_ERROR_OPERAND 0x00010000 // operand isn't allowed
125 |
126 | On case of "F_ERROR_OPCODE" flag, under notion opcode is understood not only
127 | "hde64s.opcode(2)" byte, but besides opcode's extension in ModR/M.reg, ModR/M
128 | or prefix (when two-byte opcode). So, HDE64C detects commands like "c6 c8 00"
129 | as invalid, because opcode "c6 /1" is invalid.
130 |
131 | If HDE64C setted flag "F_ERROR_LENGTH", then field "hde64s.len" is 15, so
132 | maximal value of "hde64s.len" is 15.
133 |
134 | If engine detect instruction as invalid, it doesn't stop disassembling and
135 | continue disassembling in general rules, but error flag (F_ERROR) and flag
136 | of error's type (F_ERROR_*) will be setted.
137 |
138 | 4. Contacts
139 | ===========
140 |
141 | Author: Vyacheslav Patkov
142 | E-mail: patkov-mail at mail.ru
143 | WWW: http://hde32.narod.ru/
144 |
145 | Please, mail me on russian or english language. Use text format of email, don't
146 | send me beautiful HTML or (oh my god) DOC messages.
147 |
148 | P. S.
149 |
150 | I'm boring with HDE64. So, the version is final. And maybe there are bugs (but
151 | I have no bug reports yet, and the engine succesfully passed my own tests).
152 | If YOU want continute HDE64 history -- fork it.
153 |
--------------------------------------------------------------------------------
/hde64c/doc/ru/manual.txt:
--------------------------------------------------------------------------------
1 |
2 | Hacker Disassembler Engine 64 C 0.04 FINAL
3 | ==========================================
4 |
5 | 1. Что это такое?
6 | 2. Как использовать?
7 | 3. Неправильные инструкции
8 | 4. Контакты
9 |
10 | Прежде, чем использовать HDE64, обязательно прочти данное руководство, чтобы
11 | потом не было неприятных неожиданностей. Предполагается, что читатель хотя бы
12 | немного разбирается в процессорах x86-64 и под рукой у него есть Интеловские
13 | мануалы или другие справочники. Руководство написано в разговорном стиле, слова
14 | "инструкция" и "каманда" я употреблял как синонимы. Для ассемблерных мнемоник
15 | использовался intel-синтаксис (как в nasm), прототипы и определения записаны
16 | в Си-нотации.
17 |
18 | 1. Что это такое?
19 | =================
20 |
21 | Небольшой дизассемблерный движок, предназначенный для анализа x86-64 кода.
22 | HDE64 получает информацию о команде (длина, префиксы, опкод, ModR/M,..), а
23 | также анализирует ее на вилидность. Движок может пригодиться, например, при
24 | работе с исполняемыми файлами, написании вирусов, когда простого дизассемблера
25 | длин недостаточно, а большой дизассемблер тащить тяжело, к тому же большинство
26 | из них служат лишь для получения человекочитаемой мнемоники. HDE64 предназначен
27 | для "внутреннего" анализа, поэтому поддержки мнемоник в нем принципиально
28 | никогда не будет. Из-за этого он очень мал, но получает достаточно информации
29 | для анализа.
30 |
31 | + поддержка General-Purpose, FPU, MMX, SSE-SSE3, 3DNow! инструкций
32 | + высокая скорость и маленький размер (~ 2.5 кб)
33 | + не привязан ни к какой ОС
34 |
35 | 2. Как использовать?
36 | ====================
37 |
38 | Для дизассемблирования команды необходимо вызвать функцию hde64_disasm,
39 | первый аргумент -- указатель на код, второй -- указатель на структуру hde64s:
40 |
41 | unsigned int hde64_disasm(const void *code, hde64s *hs);
42 |
43 | Аргументы следует передавать в C конвенции. Функция возвращает длину команды,
44 | а также заполняет структуру "hde64s":
45 |
46 | typedef struct {
47 | uint8_t len; // длина команды
48 | uint8_t p_rep; // префикс rep/repz (0xf3) или repnz (0xf2)
49 | uint8_t p_lock; // префикс lock: 0xf0
50 | uint8_t p_seg; // сегментный префикс: 0x26,0x2e,0x36,0x3e,0x64,0x65
51 | uint8_t p_66; // префикс переопределения размера операнда: 0x66
52 | uint8_t p_67; // префикс переопределения размера адреса: 0x67
53 | uint8_t rex; // префикс REX
54 | uint8_t rex_w; // REX.W
55 | uint8_t rex_r; // REX.R
56 | uint8_t rex_x; // REX.X
57 | uint8_t rex_b; // REX.B
58 | uint8_t opcode; // опкод
59 | uint8_t opcode2; // второй опкод (если первый 0x0f)
60 | uint8_t modrm; // ModR/M байт
61 | uint8_t modrm_mod; // ModR/M.mod
62 | uint8_t modrm_reg; // ModR/M.reg
63 | uint8_t modrm_rm; // ModR/M.r/m
64 | uint8_t sib; // SIB байт
65 | uint8_t sib_scale; // SIB.scale
66 | uint8_t sib_index; // SIB.index
67 | uint8_t sib_base; // SIB.base
68 | union {
69 | uint8_t imm8; // непосредственное значение imm8
70 | uint16_t imm16; // непосредственное значение imm16
71 | uint32_t imm32; // непосредственное значение imm32
72 | uint64_t imm64; // непосредственное значение imm64
73 | } imm;
74 | union {
75 | uint8_t disp8; // смещение disp8
76 | uint16_t disp16; // смещение disp16
77 | uint32_t disp32; // смещение disp32
78 | } disp;
79 | uint32_t flags; // флаги
80 | } hde32s;
81 |
82 | Частным случаем непосредственного значения может быть относительный адрес. В
83 | предыдущих версиях движка в структуре для них были выделены специальные поля
84 | hde64s.rel*, но теперь они записываются в свое законное место -- hde64s.imm*,
85 | а отличить их можно по флагу F_RELATIVE, который устанавливается вместе с
86 | одним из флагов F_IMM* (см. ниже).
87 |
88 | Выравнивание структуры "hde64s" равно 1 байту, т.е. его нет. Помните это при
89 | работе с компиляторами, которые любят выранивать данные по кратным адресам.
90 | Рекомендую брать хидеры из этого дистрибутива, там все настроено.
91 |
92 | Поля "hde64s.opcode" и "hde64s.len" заполняются всегда. Присутствие остальных
93 | полей следует определять по следущим флагам поля "hde64s.flags":
94 |
95 | #define F_MODRM 0x00000001 // присутствует ModR/M
96 | #define F_SIB 0x00000002 // присутствует SIB
97 | #define F_IMM8 0x00000004 // присутствует значение imm8
98 | #define F_IMM16 0x00000008 // присутствует значение imm16
99 | #define F_IMM32 0x00000010 // присутствует значение imm32
100 | #define F_IMM64 0x00000020 // присутствует значение imm64
101 | #define F_DISP8 0x00000040 // присутствует смещение disp8
102 | #define F_DISP16 0x00000080 // присутствует смещение disp16
103 | #define F_DISP32 0x00000100 // присутствует смещение disp32
104 | #define F_RELATIVE 0x00000200 // imm* является относительным адресом
105 | #define F_PREFIX_REPNZ 0x01000000 // присутствует префикс repnz
106 | #define F_PREFIX_REPX 0x02000000 // присутствует префикс rep(z)
107 | #define F_PREFIX_REP 0x03000000 // присутствует префикс rep(z) или repnz
108 | #define F_PREFIX_66 0x04000000 // присутствует префикс 0x66
109 | #define F_PREFIX_67 0x08000000 // присутствует префикс 0x67
110 | #define F_PREFIX_LOCK 0x10000000 // присутствует префикс lock
111 | #define F_PREFIX_SEG 0x20000000 // присутствует префикс сегмента
112 | #define F_PREFIX_REX 0x40000000 // присутствует префикс REX
113 | #define F_PREFIX_ANY 0x7f000000 // присутствует любой префикс
114 |
115 | Движок гарантирует, что он прочитает, начиная с места в памяти, на которое
116 | указывает "const void *code", не более 26 байт. Причем если инструкция
117 | правильная (см. п.3), то движок прочитает не более "hde64s.len" байт, которое,
118 | в свою очередь, не больше 15.
119 |
120 | 3. Неправильные инструкции
121 | ==========================
122 |
123 | HDE64C анализирует команды на правильность, причем достаточно тщательно, а не
124 | просто беглой проверкой опкода и длины (более половины размера движка занимает
125 | код и таблицы для определения ошибочных инструкций). Если HDE64C считает
126 | команду ошибочной, он устанавливает флаг "F_ERROR" в поле флагов:
127 |
128 | #define F_ERROR 0x00001000 // инструкция неправильная
129 |
130 | Кроме того, устанавливаются следущие флаги, которые немного проясняют причины
131 | установки флага ошибки:
132 |
133 | #define F_ERROR_OPCODE 0x00002000 // неправильный опкод
134 | #define F_ERROR_LENGTH 0x00004000 // длина инструкции больше 15 байт
135 | #define F_ERROR_LOCK 0x00008000 // префикс lock недопустим
136 | #define F_ERROR_OPERAND 0x00010000 // недопустимый операнд
137 |
138 | В случае флага "F_ERROR_OPCODE" под опкодом понимается не только байт, который
139 | записан в "hde64s.opcode(2)" но и его расширение за счет ModR/M.reg, всего
140 | ModR/M или префикса (для двухбайтовых опкодов), так что команды типа "c6 c8 00"
141 | будут верно определяться как ошибочные, т.к. опкод "c6 /1" ошибочный.
142 |
143 | Если движок установил флаг "F_ERROR_LENGTH", то в качестве длины команды он
144 | вернет 15, т.о. максимальное значение поля "hde64s.len" равно 15.
145 |
146 | Если движок определил команду как ошибочную, то дизассемблирование на этом
147 | не останавливается, а продолжается по общим правилам, просто ко всему прочему
148 | будет установлен флаг ошибки (F_ERROR) и причины ошибки (F_ERROR_*).
149 |
150 | 4. Контакты
151 | ===========
152 |
153 | Автор: Вячеслав Патьков
154 | E-mail: patkov-mail на mail.ru
155 | WWW: http://hde32.narod.ru/
156 |
157 | Пожалуйста, пишите письма на русском или английском языке, в обычном текстовом
158 | виде, не надо мне слать красивые письма в HTML или (еще хуже) в DOC.
159 |
160 | P. S.
161 |
162 | Мне скучно с HDE64. Поэтому, скорее всего, эта версия последняя. И не исключено,
163 | что есть баги (но пока я ни одного сообщения о них не получал, и мои тесты движок
164 | прошёл). Если ВЫ хотите развивать HDE64 -- fork'айте на здоровье.
165 |
--------------------------------------------------------------------------------
/hde64c/examples/example.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "../include/hde64.h"
3 |
4 | char fmt[] = "\n"
5 | " mov rax,0x1122334455667788\n\n"
6 | " length of command: 0x%02x\n"
7 | " immediate64: 0x%08x%08x\n";
8 |
9 | unsigned char code[] = {0x48,0xb8,0x88,0x77,0x66,0x55,0x44,0x33,0x22,0x11};
10 |
11 | int main(void)
12 | {
13 | hde64s hs;
14 |
15 | unsigned int length = hde64_disasm(code,&hs);
16 |
17 | if (hs.flags & F_ERROR)
18 | printf("Invalid instruction !\n");
19 | else
20 | printf(fmt,length,(uint32_t)(hs.imm.imm64 >> 32),
21 | (uint32_t)hs.imm.imm64);
22 |
23 | return 0;
24 | }
25 |
--------------------------------------------------------------------------------
/hde64c/include/hde64.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Hacker Disassembler Engine 64
3 | * Copyright (c) 2008-2009, Vyacheslav Patkov.
4 | * All rights reserved.
5 | *
6 | * hde64.h: C/C++ header file
7 | *
8 | */
9 |
10 | #ifndef _HDE64_H_
11 | #define _HDE64_H_
12 |
13 | /* stdint.h - C99 standard header
14 | * http://en.wikipedia.org/wiki/stdint.h
15 | *
16 | * if your compiler doesn't contain "stdint.h" header (for
17 | * example, Microsoft Visual C++), you can download file:
18 | * http://www.azillionmonkeys.com/qed/pstdint.h
19 | * and change next line to:
20 | * #include "pstdint.h"
21 | */
22 | #include
23 |
24 | #define F_MODRM 0x00000001
25 | #define F_SIB 0x00000002
26 | #define F_IMM8 0x00000004
27 | #define F_IMM16 0x00000008
28 | #define F_IMM32 0x00000010
29 | #define F_IMM64 0x00000020
30 | #define F_DISP8 0x00000040
31 | #define F_DISP16 0x00000080
32 | #define F_DISP32 0x00000100
33 | #define F_RELATIVE 0x00000200
34 | #define F_ERROR 0x00001000
35 | #define F_ERROR_OPCODE 0x00002000
36 | #define F_ERROR_LENGTH 0x00004000
37 | #define F_ERROR_LOCK 0x00008000
38 | #define F_ERROR_OPERAND 0x00010000
39 | #define F_PREFIX_REPNZ 0x01000000
40 | #define F_PREFIX_REPX 0x02000000
41 | #define F_PREFIX_REP 0x03000000
42 | #define F_PREFIX_66 0x04000000
43 | #define F_PREFIX_67 0x08000000
44 | #define F_PREFIX_LOCK 0x10000000
45 | #define F_PREFIX_SEG 0x20000000
46 | #define F_PREFIX_REX 0x40000000
47 | #define F_PREFIX_ANY 0x7f000000
48 |
49 | #define PREFIX_SEGMENT_CS 0x2e
50 | #define PREFIX_SEGMENT_SS 0x36
51 | #define PREFIX_SEGMENT_DS 0x3e
52 | #define PREFIX_SEGMENT_ES 0x26
53 | #define PREFIX_SEGMENT_FS 0x64
54 | #define PREFIX_SEGMENT_GS 0x65
55 | #define PREFIX_LOCK 0xf0
56 | #define PREFIX_REPNZ 0xf2
57 | #define PREFIX_REPX 0xf3
58 | #define PREFIX_OPERAND_SIZE 0x66
59 | #define PREFIX_ADDRESS_SIZE 0x67
60 |
61 | #pragma pack(push,1)
62 |
63 | typedef struct {
64 | uint8_t len;
65 | uint8_t p_rep;
66 | uint8_t p_lock;
67 | uint8_t p_seg;
68 | uint8_t p_66;
69 | uint8_t p_67;
70 | uint8_t rex;
71 | uint8_t rex_w;
72 | uint8_t rex_r;
73 | uint8_t rex_x;
74 | uint8_t rex_b;
75 | uint8_t opcode;
76 | uint8_t opcode2;
77 | uint8_t modrm;
78 | uint8_t modrm_mod;
79 | uint8_t modrm_reg;
80 | uint8_t modrm_rm;
81 | uint8_t sib;
82 | uint8_t sib_scale;
83 | uint8_t sib_index;
84 | uint8_t sib_base;
85 | union {
86 | uint8_t imm8;
87 | uint16_t imm16;
88 | uint32_t imm32;
89 | uint64_t imm64;
90 | } imm;
91 | union {
92 | uint8_t disp8;
93 | uint16_t disp16;
94 | uint32_t disp32;
95 | } disp;
96 | uint32_t flags;
97 | } hde64s;
98 |
99 | #pragma pack(pop)
100 |
101 | #ifdef __cplusplus
102 | extern "C" {
103 | #endif
104 |
105 | /* __cdecl */
106 | unsigned int hde64_disasm(const void *code, hde64s *hs);
107 |
108 | #ifdef __cplusplus
109 | }
110 | #endif
111 |
112 | #endif /* _HDE64_H_ */
113 |
--------------------------------------------------------------------------------
/hde64c/src/hde64.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Hacker Disassembler Engine 64 C
3 | * Copyright (c) 2008-2009, Vyacheslav Patkov.
4 | * All rights reserved.
5 | *
6 | */
7 |
8 | #include
9 | #include
10 |
11 | #include "../include/hde64.h"
12 | #include "table64.h"
13 |
14 | unsigned int hde64_disasm(const void *code, hde64s *hs)
15 | {
16 | uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0;
17 | uint8_t *ht = hde64_table, m_mod, m_reg, m_rm, disp_size = 0;
18 | uint8_t op64 = 0;
19 |
20 | memset(hs,0,sizeof(hde64s));
21 |
22 | for (x = 16; x; x--)
23 | switch (c = *p++) {
24 | case 0xf3:
25 | hs->p_rep = c;
26 | pref |= PRE_F3;
27 | break;
28 | case 0xf2:
29 | hs->p_rep = c;
30 | pref |= PRE_F2;
31 | break;
32 | case 0xf0:
33 | hs->p_lock = c;
34 | pref |= PRE_LOCK;
35 | break;
36 | case 0x26: case 0x2e: case 0x36:
37 | case 0x3e: case 0x64: case 0x65:
38 | hs->p_seg = c;
39 | pref |= PRE_SEG;
40 | break;
41 | case 0x66:
42 | hs->p_66 = c;
43 | pref |= PRE_66;
44 | break;
45 | case 0x67:
46 | hs->p_67 = c;
47 | pref |= PRE_67;
48 | break;
49 | default:
50 | goto pref_done;
51 | }
52 | pref_done:
53 |
54 | hs->flags = (uint32_t)pref << 23;
55 |
56 | if (!pref)
57 | pref |= PRE_NONE;
58 |
59 | if ((c & 0xf0) == 0x40) {
60 | hs->flags |= F_PREFIX_REX;
61 | if ((hs->rex_w = (c & 0xf) >> 3) && (*p & 0xf8) == 0xb8)
62 | op64++;
63 | hs->rex_r = (c & 7) >> 2;
64 | hs->rex_x = (c & 3) >> 1;
65 | hs->rex_b = c & 1;
66 | if (((c = *p++) & 0xf0) == 0x40) {
67 | opcode = c;
68 | goto error_opcode;
69 | }
70 | }
71 |
72 | if ((hs->opcode = c) == 0x0f) {
73 | hs->opcode2 = c = *p++;
74 | ht += DELTA_OPCODES;
75 | } else if (c >= 0xa0 && c <= 0xa3) {
76 | op64++;
77 | if (pref & PRE_67)
78 | pref |= PRE_66;
79 | else
80 | pref &= ~PRE_66;
81 | }
82 |
83 | opcode = c;
84 | cflags = ht[ht[opcode / 4] + (opcode % 4)];
85 |
86 | if (cflags == C_ERROR) {
87 | error_opcode:
88 | hs->flags |= F_ERROR | F_ERROR_OPCODE;
89 | cflags = 0;
90 | if ((opcode & -3) == 0x24)
91 | cflags++;
92 | }
93 |
94 | x = 0;
95 | if (cflags & C_GROUP) {
96 | uint16_t t;
97 | t = *(uint16_t *)(ht + (cflags & 0x7f));
98 | cflags = (uint8_t)t;
99 | x = (uint8_t)(t >> 8);
100 | }
101 |
102 | if (hs->opcode2) {
103 | ht = hde64_table + DELTA_PREFIXES;
104 | if (ht[ht[opcode / 4] + (opcode % 4)] & pref)
105 | hs->flags |= F_ERROR | F_ERROR_OPCODE;
106 | }
107 |
108 | if (cflags & C_MODRM) {
109 | hs->flags |= F_MODRM;
110 | hs->modrm = c = *p++;
111 | hs->modrm_mod = m_mod = c >> 6;
112 | hs->modrm_rm = m_rm = c & 7;
113 | hs->modrm_reg = m_reg = (c & 0x3f) >> 3;
114 |
115 | if (x && ((x << m_reg) & 0x80))
116 | hs->flags |= F_ERROR | F_ERROR_OPCODE;
117 |
118 | if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) {
119 | uint8_t t = opcode - 0xd9;
120 | if (m_mod == 3) {
121 | ht = hde64_table + DELTA_FPU_MODRM + t*8;
122 | t = ht[m_reg] << m_rm;
123 | } else {
124 | ht = hde64_table + DELTA_FPU_REG;
125 | t = ht[t] << m_reg;
126 | }
127 | if (t & 0x80)
128 | hs->flags |= F_ERROR | F_ERROR_OPCODE;
129 | }
130 |
131 | if (pref & PRE_LOCK) {
132 | if (m_mod == 3) {
133 | hs->flags |= F_ERROR | F_ERROR_LOCK;
134 | } else {
135 | uint8_t *table_end, op = opcode;
136 | if (hs->opcode2) {
137 | ht = hde64_table + DELTA_OP2_LOCK_OK;
138 | table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK;
139 | } else {
140 | ht = hde64_table + DELTA_OP_LOCK_OK;
141 | table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK;
142 | op &= -2;
143 | }
144 | for (; ht != table_end; ht++)
145 | if (*ht++ == op) {
146 | if (!((*ht << m_reg) & 0x80))
147 | goto no_lock_error;
148 | else
149 | break;
150 | }
151 | hs->flags |= F_ERROR | F_ERROR_LOCK;
152 | no_lock_error:
153 | ;
154 | }
155 | }
156 |
157 | if (hs->opcode2) {
158 | switch (opcode) {
159 | case 0x20: case 0x22:
160 | m_mod = 3;
161 | if (m_reg > 4 || m_reg == 1)
162 | goto error_operand;
163 | else
164 | goto no_error_operand;
165 | case 0x21: case 0x23:
166 | m_mod = 3;
167 | if (m_reg == 4 || m_reg == 5)
168 | goto error_operand;
169 | else
170 | goto no_error_operand;
171 | }
172 | } else {
173 | switch (opcode) {
174 | case 0x8c:
175 | if (m_reg > 5)
176 | goto error_operand;
177 | else
178 | goto no_error_operand;
179 | case 0x8e:
180 | if (m_reg == 1 || m_reg > 5)
181 | goto error_operand;
182 | else
183 | goto no_error_operand;
184 | }
185 | }
186 |
187 | if (m_mod == 3) {
188 | uint8_t *table_end;
189 | if (hs->opcode2) {
190 | ht = hde64_table + DELTA_OP2_ONLY_MEM;
191 | table_end = ht + sizeof(hde64_table) - DELTA_OP2_ONLY_MEM;
192 | } else {
193 | ht = hde64_table + DELTA_OP_ONLY_MEM;
194 | table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM;
195 | }
196 | for (; ht != table_end; ht += 2)
197 | if (*ht++ == opcode) {
198 | if (*ht++ & pref && !((*ht << m_reg) & 0x80))
199 | goto error_operand;
200 | else
201 | break;
202 | }
203 | goto no_error_operand;
204 | } else if (hs->opcode2) {
205 | switch (opcode) {
206 | case 0x50: case 0xd7: case 0xf7:
207 | if (pref & (PRE_NONE | PRE_66))
208 | goto error_operand;
209 | break;
210 | case 0xd6:
211 | if (pref & (PRE_F2 | PRE_F3))
212 | goto error_operand;
213 | break;
214 | case 0xc5:
215 | goto error_operand;
216 | }
217 | goto no_error_operand;
218 | } else
219 | goto no_error_operand;
220 |
221 | error_operand:
222 | hs->flags |= F_ERROR | F_ERROR_OPERAND;
223 | no_error_operand:
224 |
225 | c = *p++;
226 | if (m_reg <= 1) {
227 | if (opcode == 0xf6)
228 | cflags |= C_IMM8;
229 | else if (opcode == 0xf7)
230 | cflags |= C_IMM_P66;
231 | }
232 |
233 | switch (m_mod) {
234 | case 0:
235 | if (pref & PRE_67) {
236 | if (m_rm == 6)
237 | disp_size = 2;
238 | } else
239 | if (m_rm == 5)
240 | disp_size = 4;
241 | break;
242 | case 1:
243 | disp_size = 1;
244 | break;
245 | case 2:
246 | disp_size = 2;
247 | if (!(pref & PRE_67))
248 | disp_size <<= 1;
249 | }
250 |
251 | if (m_mod != 3 && m_rm == 4) {
252 | hs->flags |= F_SIB;
253 | p++;
254 | hs->sib = c;
255 | hs->sib_scale = c >> 6;
256 | hs->sib_index = (c & 0x3f) >> 3;
257 | if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1))
258 | disp_size = 4;
259 | }
260 |
261 | p--;
262 | switch (disp_size) {
263 | case 1:
264 | hs->flags |= F_DISP8;
265 | hs->disp.disp8 = *p;
266 | break;
267 | case 2:
268 | hs->flags |= F_DISP16;
269 | hs->disp.disp16 = *(uint16_t *)p;
270 | break;
271 | case 4:
272 | hs->flags |= F_DISP32;
273 | hs->disp.disp32 = *(uint32_t *)p;
274 | }
275 | p += disp_size;
276 | } else if (pref & PRE_LOCK)
277 | hs->flags |= F_ERROR | F_ERROR_LOCK;
278 |
279 | if (cflags & C_IMM_P66) {
280 | if (cflags & C_REL32) {
281 | if (pref & PRE_66) {
282 | hs->flags |= F_IMM16 | F_RELATIVE;
283 | hs->imm.imm16 = *(uint16_t *)p;
284 | p += 2;
285 | goto disasm_done;
286 | }
287 | goto rel32_ok;
288 | }
289 | if (op64) {
290 | hs->flags |= F_IMM64;
291 | hs->imm.imm64 = *(uint64_t *)p;
292 | p += 8;
293 | } else if (!(pref & PRE_66)) {
294 | hs->flags |= F_IMM32;
295 | hs->imm.imm32 = *(uint32_t *)p;
296 | p += 4;
297 | } else
298 | goto imm16_ok;
299 | }
300 |
301 |
302 | if (cflags & C_IMM16) {
303 | imm16_ok:
304 | hs->flags |= F_IMM16;
305 | hs->imm.imm16 = *(uint16_t *)p;
306 | p += 2;
307 | }
308 | if (cflags & C_IMM8) {
309 | hs->flags |= F_IMM8;
310 | hs->imm.imm8 = *p++;
311 | }
312 |
313 | if (cflags & C_REL32) {
314 | rel32_ok:
315 | hs->flags |= F_IMM32 | F_RELATIVE;
316 | hs->imm.imm32 = *(uint32_t *)p;
317 | p += 4;
318 | } else if (cflags & C_REL8) {
319 | hs->flags |= F_IMM8 | F_RELATIVE;
320 | hs->imm.imm8 = *p++;
321 | }
322 |
323 | disasm_done:
324 |
325 | if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) {
326 | hs->flags |= F_ERROR | F_ERROR_LENGTH;
327 | hs->len = 15;
328 | }
329 |
330 | return (unsigned int)hs->len;
331 | }
332 |
--------------------------------------------------------------------------------
/hde64c/src/table64.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Hacker Disassembler Engine 64 C
3 | * Copyright (c) 2008-2009, Vyacheslav Patkov.
4 | * All rights reserved.
5 | *
6 | */
7 |
8 | #define C_NONE 0x00
9 | #define C_MODRM 0x01
10 | #define C_IMM8 0x02
11 | #define C_IMM16 0x04
12 | #define C_IMM_P66 0x10
13 | #define C_REL8 0x20
14 | #define C_REL32 0x40
15 | #define C_GROUP 0x80
16 | #define C_ERROR 0xff
17 |
18 | #define PRE_ANY 0x00
19 | #define PRE_NONE 0x01
20 | #define PRE_F2 0x02
21 | #define PRE_F3 0x04
22 | #define PRE_66 0x08
23 | #define PRE_67 0x10
24 | #define PRE_LOCK 0x20
25 | #define PRE_SEG 0x40
26 | #define PRE_ALL 0xff
27 |
28 | #define DELTA_OPCODES 0x4a
29 | #define DELTA_FPU_REG 0xfd
30 | #define DELTA_FPU_MODRM 0x104
31 | #define DELTA_PREFIXES 0x13c
32 | #define DELTA_OP_LOCK_OK 0x1ae
33 | #define DELTA_OP2_LOCK_OK 0x1c6
34 | #define DELTA_OP_ONLY_MEM 0x1d8
35 | #define DELTA_OP2_ONLY_MEM 0x1e7
36 |
37 | unsigned char hde64_table[] = {
38 | 0xa5,0xaa,0xa5,0xb8,0xa5,0xaa,0xa5,0xaa,0xa5,0xb8,0xa5,0xb8,0xa5,0xb8,0xa5,
39 | 0xb8,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xac,0xc0,0xcc,0xc0,0xa1,0xa1,
40 | 0xa1,0xa1,0xb1,0xa5,0xa5,0xa6,0xc0,0xc0,0xd7,0xda,0xe0,0xc0,0xe4,0xc0,0xea,
41 | 0xea,0xe0,0xe0,0x98,0xc8,0xee,0xf1,0xa5,0xd3,0xa5,0xa5,0xa1,0xea,0x9e,0xc0,
42 | 0xc0,0xc2,0xc0,0xe6,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0xab,
43 | 0x8b,0x90,0x64,0x5b,0x5b,0x5b,0x5b,0x5b,0x92,0x5b,0x5b,0x76,0x90,0x92,0x92,
44 | 0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x6a,0x73,0x90,
45 | 0x5b,0x52,0x52,0x52,0x52,0x5b,0x5b,0x5b,0x5b,0x77,0x7c,0x77,0x85,0x5b,0x5b,
46 | 0x70,0x5b,0x7a,0xaf,0x76,0x76,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,
47 | 0x5b,0x5b,0x86,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xd5,0x03,0xcc,0x01,0xbc,
48 | 0x03,0xf0,0x03,0x03,0x04,0x00,0x50,0x50,0x50,0x50,0xff,0x20,0x20,0x20,0x20,
49 | 0x01,0x01,0x01,0x01,0xc4,0x02,0x10,0xff,0xff,0xff,0x01,0x00,0x03,0x11,0xff,
50 | 0x03,0xc4,0xc6,0xc8,0x02,0x10,0x00,0xff,0xcc,0x01,0x01,0x01,0x00,0x00,0x00,
51 | 0x00,0x01,0x01,0x03,0x01,0xff,0xff,0xc0,0xc2,0x10,0x11,0x02,0x03,0x01,0x01,
52 | 0x01,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x10,
53 | 0x10,0x10,0x10,0x02,0x10,0x00,0x00,0xc6,0xc8,0x02,0x02,0x02,0x02,0x06,0x00,
54 | 0x04,0x00,0x02,0xff,0x00,0xc0,0xc2,0x01,0x01,0x03,0x03,0x03,0xca,0x40,0x00,
55 | 0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00,0x00,0x00,0x00,
56 | 0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xff,0x00,
57 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,
58 | 0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00,
59 | 0xff,0x40,0x40,0x40,0x40,0x41,0x49,0x40,0x40,0x40,0x40,0x4c,0x42,0x40,0x40,
60 | 0x40,0x40,0x40,0x40,0x40,0x40,0x4f,0x44,0x53,0x40,0x40,0x40,0x44,0x57,0x43,
61 | 0x5c,0x40,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
62 | 0x40,0x40,0x64,0x66,0x6e,0x6b,0x40,0x40,0x6a,0x46,0x40,0x40,0x44,0x46,0x40,
63 | 0x40,0x5b,0x44,0x40,0x40,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x01,0x06,
64 | 0x06,0x02,0x06,0x06,0x00,0x06,0x00,0x0a,0x0a,0x00,0x00,0x00,0x02,0x07,0x07,
65 | 0x06,0x02,0x0d,0x06,0x06,0x06,0x0e,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04,
66 | 0x04,0x04,0x05,0x06,0x06,0x06,0x00,0x00,0x00,0x0e,0x00,0x00,0x08,0x00,0x10,
67 | 0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01,0x86,0x00,
68 | 0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba,0xf8,0xbb,
69 | 0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00,0xc4,0xff,
70 | 0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00,0x13,0x09,
71 | 0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07,0xb2,0xff,
72 | 0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf,0xe7,0x08,
73 | 0x00,0xf0,0x02,0x00
74 | };
75 |
--------------------------------------------------------------------------------
/include/System/machine/cpu_capabilities.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
3 | *
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 | *
6 | * This file contains Original Code and/or Modifications of Original Code
7 | * as defined in and that are subject to the Apple Public Source License
8 | * Version 2.0 (the 'License'). You may not use this file except in
9 | * compliance with the License. The rights granted to you under the License
10 | * may not be used to create, or enable the creation or redistribution of,
11 | * unlawful or unlicensed copies of an Apple operating system, or to
12 | * circumvent, violate, or enable the circumvention or violation of, any
13 | * terms of an Apple operating system software license agreement.
14 | *
15 | * Please obtain a copy of the License at
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 | *
18 | * The Original Code and all software distributed under the License are
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 | * Please see the License for the specific language governing rights and
24 | * limitations under the License.
25 | *
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 | */
28 | #ifdef PRIVATE
29 |
30 | #ifndef _MACHINE_CPU_CAPABILITIES_H
31 | #define _MACHINE_CPU_CAPABILITIES_H
32 |
33 | #ifdef KERNEL_PRIVATE
34 | #if defined (__ppc__)
35 | #include "ppc/cpu_capabilities.h"
36 | #elif defined (__i386__)
37 | #include "i386/cpu_capabilities.h"
38 | #else
39 | #error architecture not supported
40 | #endif
41 |
42 | #else /* !KERNEL_PRIVATE -- System Framework header */
43 | #if defined (__ppc__) || defined(__ppc64__)
44 | #include
45 | #elif defined (__i386__) || defined(__x86_64__)
46 | #include
47 | #else
48 | #error architecture not supported
49 | #endif
50 | #endif /* KERNEL_PRIVATE */
51 |
52 | #endif /* _MACHINE_CPU_CAPABILITIES_H */
53 | #endif /* PRIVATE */
54 |
--------------------------------------------------------------------------------
/include/machine/cpu_capabilities.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
3 | *
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 | *
6 | * This file contains Original Code and/or Modifications of Original Code
7 | * as defined in and that are subject to the Apple Public Source License
8 | * Version 2.0 (the 'License'). You may not use this file except in
9 | * compliance with the License. The rights granted to you under the License
10 | * may not be used to create, or enable the creation or redistribution of,
11 | * unlawful or unlicensed copies of an Apple operating system, or to
12 | * circumvent, violate, or enable the circumvention or violation of, any
13 | * terms of an Apple operating system software license agreement.
14 | *
15 | * Please obtain a copy of the License at
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 | *
18 | * The Original Code and all software distributed under the License are
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 | * Please see the License for the specific language governing rights and
24 | * limitations under the License.
25 | *
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 | */
28 | #ifdef PRIVATE
29 |
30 | #ifndef _MACHINE_CPU_CAPABILITIES_H
31 | #define _MACHINE_CPU_CAPABILITIES_H
32 |
33 | #ifdef KERNEL_PRIVATE
34 | #if defined (__ppc__)
35 | #include "ppc/cpu_capabilities.h"
36 | #elif defined (__i386__)
37 | #include "i386/cpu_capabilities.h"
38 | #else
39 | #error architecture not supported
40 | #endif
41 |
42 | #else /* !KERNEL_PRIVATE -- System Framework header */
43 | #if defined (__ppc__) || defined(__ppc64__)
44 | #include
45 | #elif defined (__i386__) || defined(__x86_64__)
46 | #include
47 | #else
48 | #error architecture not supported
49 | #endif
50 | #endif /* KERNEL_PRIVATE */
51 |
52 | #endif /* _MACHINE_CPU_CAPABILITIES_H */
53 | #endif /* PRIVATE */
54 |
--------------------------------------------------------------------------------
/include/posix_sched.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
3 | *
4 | * @APPLE_LICENSE_HEADER_START@
5 | *
6 | * This file contains Original Code and/or Modifications of Original Code
7 | * as defined in and that are subject to the Apple Public Source License
8 | * Version 2.0 (the 'License'). You may not use this file except in
9 | * compliance with the License. Please obtain a copy of the License at
10 | * http://www.opensource.apple.com/apsl/ and read it before using this
11 | * file.
12 | *
13 | * The Original Code and all software distributed under the License are
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 | * Please see the License for the specific language governing rights and
19 | * limitations under the License.
20 | *
21 | * @APPLE_LICENSE_HEADER_END@
22 | */
23 | /*
24 | * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
25 | * All Rights Reserved
26 | *
27 | * Permission to use, copy, modify, and distribute this software and
28 | * its documentation for any purpose and without fee is hereby granted,
29 | * provided that the above copyright notice appears in all copies and
30 | * that both the copyright notice and this permission notice appear in
31 | * supporting documentation.
32 | *
33 | * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
34 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
35 | * FOR A PARTICULAR PURPOSE.
36 | *
37 | * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
38 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
39 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
40 | * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
41 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
42 | *
43 | */
44 | /*
45 | * MkLinux
46 | */
47 |
48 | /*
49 | * POSIX Realtime Scheduling Framework - IEEE 1003.1b
50 | */
51 |
52 | #ifndef _POSIX_SCHED_H
53 | #define _POSIX_SCHED_H
54 |
55 | struct sched_param
56 | {
57 | int sched_priority;
58 | int quantum;
59 | };
60 |
61 | /*
62 | * POSIX scheduling policies
63 | */
64 |
65 | #define SCHED_OTHER POLICY_TIMESHARE
66 | #define SCHED_FIFO POLICY_FIFO
67 | #define SCHED_RR POLICY_RR
68 |
69 | #endif /* _POSIX_SCHED_H */
70 |
--------------------------------------------------------------------------------
/include/pthread_machdep.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003-2004, 2008 Apple Inc. All rights reserved.
3 | *
4 | * @APPLE_LICENSE_HEADER_START@
5 | *
6 | * This file contains Original Code and/or Modifications of Original Code
7 | * as defined in and that are subject to the Apple Public Source License
8 | * Version 2.0 (the 'License'). You may not use this file except in
9 | * compliance with the License. Please obtain a copy of the License at
10 | * http://www.opensource.apple.com/apsl/ and read it before using this
11 | * file.
12 | *
13 | * The Original Code and all software distributed under the License are
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 | * Please see the License for the specific language governing rights and
19 | * limitations under the License.
20 | *
21 | * @APPLE_LICENSE_HEADER_END@
22 | */
23 | /*
24 | * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
25 | * All Rights Reserved
26 | *
27 | * Permission to use, copy, modify, and distribute this software and
28 | * its documentation for any purpose and without fee is hereby granted,
29 | * provided that the above copyright notice appears in all copies and
30 | * that both the copyright notice and this permission notice appear in
31 | * supporting documentation.
32 | *
33 | * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
34 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
35 | * FOR A PARTICULAR PURPOSE.
36 | *
37 | * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
38 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
39 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
40 | * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
41 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
42 | */
43 | /*
44 | * MkLinux
45 | */
46 |
47 | /* Machine-dependent definitions for pthread internals. */
48 |
49 | #ifndef _POSIX_PTHREAD_MACHDEP_H
50 | #define _POSIX_PTHREAD_MACHDEP_H
51 |
52 | #ifndef __ASSEMBLER__
53 |
54 | #include
55 | #ifdef __arm__
56 | #include
57 | #endif
58 | #include
59 |
60 | /*
61 | ** Define macros for inline pthread_getspecific() usage.
62 | ** We reserve a number of slots for Apple internal use.
63 | ** This number can grow dynamically, no need to fix it.
64 | */
65 |
66 | /* This header contains pre defined thread specific keys */
67 | /* 0 is used for pthread_self */
68 | #define _PTHREAD_TSD_SLOT_PTHREAD_SELF 0
69 | /* Keys 1- 9 for use by dyld, directly or indirectly */
70 | #define _PTHREAD_TSD_SLOT_DYLD_1 1
71 | #define _PTHREAD_TSD_SLOT_DYLD_2 2
72 | #define _PTHREAD_TSD_SLOT_DYLD_3 3
73 | #define _PTHREAD_TSD_RESERVED_SLOT_COUNT 4
74 | /* To mirror the usage by dyld for Unwind_SjLj */
75 | #define _PTHREAD_TSD_SLOT_DYLD_8 8
76 |
77 | /* Keys 10 - 29 are for Libc/Libsystem internal ussage */
78 | /* used as __pthread_tsd_first + Num */
79 | #define __PTK_LIBC_LOCALE_KEY 10
80 | #define __PTK_LIBC_TTYNAME_KEY 11
81 | #define __PTK_LIBC_LOCALTIME_KEY 12
82 | #define __PTK_LIBC_GMTIME_KEY 13
83 | #define __PTK_LIBC_GDTOA_BIGINT_KEY 14
84 | #define __PTK_LIBC_PARSEFLOAT_KEY 15
85 | /* for usage by dyld */
86 | #define __PTK_LIBC_DYLD_Unwind_SjLj_Key 18
87 |
88 | /* Keys 20-25 for libdispactch usage */
89 | #define __PTK_LIBDISPATCH_KEY0 20
90 | #define __PTK_LIBDISPATCH_KEY1 21
91 | #define __PTK_LIBDISPATCH_KEY2 22
92 | #define __PTK_LIBDISPATCH_KEY3 23
93 | #define __PTK_LIBDISPATCH_KEY4 24
94 | #define __PTK_LIBDISPATCH_KEY5 25
95 |
96 | /* Keys 30-255 for Non Libsystem usage */
97 |
98 | /* Keys 30-39 for Graphic frameworks usage */
99 | #define _PTHREAD_TSD_SLOT_OPENGL 30 /* backwards compat sake */
100 | #define __PTK_FRAMEWORK_OPENGL_KEY 30
101 | #define __PTK_FRAMEWORK_GRAPHICS_KEY1 31
102 | #define __PTK_FRAMEWORK_GRAPHICS_KEY2 32
103 | #define __PTK_FRAMEWORK_GRAPHICS_KEY3 33
104 | #define __PTK_FRAMEWORK_GRAPHICS_KEY4 34
105 | #define __PTK_FRAMEWORK_GRAPHICS_KEY5 35
106 | #define __PTK_FRAMEWORK_GRAPHICS_KEY6 36
107 | #define __PTK_FRAMEWORK_GRAPHICS_KEY7 37
108 | #define __PTK_FRAMEWORK_GRAPHICS_KEY8 38
109 | #define __PTK_FRAMEWORK_GRAPHICS_KEY9 39
110 |
111 | /* Keys 40-49 for Objective-C runtime usage */
112 | #define __PTK_FRAMEWORK_OBJC_KEY0 40
113 | #define __PTK_FRAMEWORK_OBJC_KEY1 41
114 | #define __PTK_FRAMEWORK_OBJC_KEY2 42
115 | #define __PTK_FRAMEWORK_OBJC_KEY3 43
116 | #define __PTK_FRAMEWORK_OBJC_KEY4 44
117 | #define __PTK_FRAMEWORK_OBJC_KEY5 45
118 | #define __PTK_FRAMEWORK_OBJC_KEY6 46
119 | #define __PTK_FRAMEWORK_OBJC_KEY7 47
120 | #define __PTK_FRAMEWORK_OBJC_KEY8 48
121 | #define __PTK_FRAMEWORK_OBJC_KEY9 49
122 |
123 | /* Keys 50-59 for Core Foundation usage */
124 | #define __PTK_FRAMEWORK_COREFOUNDATION_KEY0 50
125 | #define __PTK_FRAMEWORK_COREFOUNDATION_KEY1 51
126 | #define __PTK_FRAMEWORK_COREFOUNDATION_KEY2 52
127 | #define __PTK_FRAMEWORK_COREFOUNDATION_KEY3 53
128 | #define __PTK_FRAMEWORK_COREFOUNDATION_KEY4 54
129 | #define __PTK_FRAMEWORK_COREFOUNDATION_KEY5 55
130 | #define __PTK_FRAMEWORK_COREFOUNDATION_KEY6 56
131 | #define __PTK_FRAMEWORK_COREFOUNDATION_KEY7 57
132 | #define __PTK_FRAMEWORK_COREFOUNDATION_KEY8 58
133 | #define __PTK_FRAMEWORK_COREFOUNDATION_KEY9 59
134 |
135 | /* Keys 60-69 for Foundation usage */
136 | #define __PTK_FRAMEWORK_FOUNDATION_KEY0 60
137 | #define __PTK_FRAMEWORK_FOUNDATION_KEY1 61
138 | #define __PTK_FRAMEWORK_FOUNDATION_KEY2 62
139 | #define __PTK_FRAMEWORK_FOUNDATION_KEY3 63
140 | #define __PTK_FRAMEWORK_FOUNDATION_KEY4 64
141 | #define __PTK_FRAMEWORK_FOUNDATION_KEY5 65
142 | #define __PTK_FRAMEWORK_FOUNDATION_KEY6 66
143 | #define __PTK_FRAMEWORK_FOUNDATION_KEY7 67
144 | #define __PTK_FRAMEWORK_FOUNDATION_KEY8 68
145 | #define __PTK_FRAMEWORK_FOUNDATION_KEY9 69
146 |
147 | /* Keys 70-79 for Core Animation/QuartzCore usage */
148 | #define __PTK_FRAMEWORK_QUARTZCORE_KEY0 70
149 | #define __PTK_FRAMEWORK_QUARTZCORE_KEY1 71
150 | #define __PTK_FRAMEWORK_QUARTZCORE_KEY2 72
151 | #define __PTK_FRAMEWORK_QUARTZCORE_KEY3 73
152 | #define __PTK_FRAMEWORK_QUARTZCORE_KEY4 74
153 | #define __PTK_FRAMEWORK_QUARTZCORE_KEY5 75
154 | #define __PTK_FRAMEWORK_QUARTZCORE_KEY6 76
155 | #define __PTK_FRAMEWORK_QUARTZCORE_KEY7 77
156 | #define __PTK_FRAMEWORK_QUARTZCORE_KEY8 78
157 | #define __PTK_FRAMEWORK_QUARTZCORE_KEY9 79
158 |
159 |
160 | /* Keys 80-89 for Garbage Collection */
161 | #define __PTK_FRAMEWORK_OLDGC_KEY0 80
162 | #define __PTK_FRAMEWORK_OLDGC_KEY1 81
163 | #define __PTK_FRAMEWORK_OLDGC_KEY2 82
164 | #define __PTK_FRAMEWORK_OLDGC_KEY3 83
165 | #define __PTK_FRAMEWORK_OLDGC_KEY4 84
166 | #define __PTK_FRAMEWORK_OLDGC_KEY5 85
167 | #define __PTK_FRAMEWORK_OLDGC_KEY6 86
168 | #define __PTK_FRAMEWORK_OLDGC_KEY7 87
169 | #define __PTK_FRAMEWORK_OLDGC_KEY8 88
170 | #define __PTK_FRAMEWORK_OLDGC_KEY9 89
171 |
172 | /* Keys 90-94 for JavaScriptCore Collection */
173 | #define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY0 90
174 | #define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY1 91
175 | #define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY2 92
176 | #define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY3 93
177 | #define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY4 94
178 |
179 | /* Keys 110-119 for Garbage Collection */
180 | #define __PTK_FRAMEWORK_GC_KEY0 110
181 | #define __PTK_FRAMEWORK_GC_KEY1 111
182 | #define __PTK_FRAMEWORK_GC_KEY2 112
183 | #define __PTK_FRAMEWORK_GC_KEY3 113
184 | #define __PTK_FRAMEWORK_GC_KEY4 114
185 | #define __PTK_FRAMEWORK_GC_KEY5 115
186 | #define __PTK_FRAMEWORK_GC_KEY6 116
187 | #define __PTK_FRAMEWORK_GC_KEY7 117
188 | #define __PTK_FRAMEWORK_GC_KEY8 118
189 | #define __PTK_FRAMEWORK_GC_KEY9 119
190 |
191 | /*
192 | ** Define macros for inline pthread_getspecific() usage.
193 | ** We reserve a number of slots for Apple internal use.
194 | ** This number can grow dynamically, no need to fix it.
195 | */
196 |
197 |
198 | #if defined(__cplusplus)
199 | extern "C" {
200 | #endif
201 |
202 | extern void *pthread_getspecific(unsigned long);
203 | /* setup destructor function for static key as it is not created with pthread_key_create() */
204 | int pthread_key_init_np(int, void (*)(void *));
205 |
206 | #if defined(__cplusplus)
207 | }
208 | #endif
209 |
210 | typedef int pthread_lock_t;
211 |
212 | #if TARGET_IPHONE_SIMULATOR
213 |
214 | /* Similator will use the host implementation, so bypass the macro that is in the target code */
215 |
216 | inline static int
217 | _pthread_has_direct_tsd(void)
218 | {
219 | return 0;
220 | }
221 |
222 | #define _pthread_getspecific_direct(key) pthread_getspecific(key)
223 | #define _pthread_setspecific_direct(key, val) pthread_setspecific(key, val)
224 |
225 | #else /* TARGET_IPHONE_SIMULATOR */
226 |
227 | inline static int
228 | _pthread_has_direct_tsd(void)
229 | {
230 | #if defined(__ppc__)
231 | int *caps = (int *)_COMM_PAGE_CPU_CAPABILITIES;
232 | if (*caps & kFastThreadLocalStorage) {
233 | return 1;
234 | } else {
235 | return 0;
236 | }
237 | #else
238 | return 1;
239 | #endif
240 | }
241 |
242 | /* To be used with static constant keys only */
243 | inline static void *
244 | _pthread_getspecific_direct(unsigned long slot)
245 | {
246 | void *ret;
247 |
248 | #if defined(__i386__) || defined(__x86_64__)
249 | asm("mov %%gs:%1, %0" : "=r" (ret) : "m" (*(void **)(slot * sizeof(void *))));
250 | #elif defined(__ppc64__) || defined(__ppc__)
251 | ret = pthread_getspecific(slot);
252 | #elif defined(__arm__) && defined(_ARM_ARCH_6) && !defined(_ARM_ARCH_7) && defined(__thumb__) && !defined(__OPTIMIZE__)
253 | ret = pthread_getspecific(slot);
254 | #elif defined(__arm__) && defined(_ARM_ARCH_6)
255 | void **__pthread_tsd;
256 | __asm__ (
257 | "mrc p15, 0, %0, c13, c0, 3\n"
258 | "bic %0, %0, #3\n"
259 | : "=r"(__pthread_tsd));
260 | ret = __pthread_tsd[slot];
261 | #elif defined(__arm__) && !defined(_ARM_ARCH_6)
262 | register void **__pthread_tsd asm ("r9");
263 | ret = __pthread_tsd[slot];
264 | #else
265 | #error no pthread_getspecific_direct implementation for this arch
266 | #endif
267 | return ret;
268 | }
269 |
270 | #if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
271 | /* To be used with static constant keys only */
272 | inline static int
273 | _pthread_setspecific_direct(unsigned long slot, void * val)
274 | {
275 |
276 | #if defined(__i386__)
277 | #if defined(__PIC__)
278 | asm("movl %1,%%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "rn" (val));
279 | #else
280 | asm("movl %1,%%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "ri" (val));
281 | #endif
282 | #elif defined(__x86_64__)
283 | /* PIC is free and cannot be disabled, even with: gcc -mdynamic-no-pic ... */
284 | asm("movq %1,%%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "rn" (val));
285 | #elif defined(__arm__) && defined(_ARM_ARCH_6)
286 | void **__pthread_tsd;
287 | __asm__ (
288 | "mrc p15, 0, %0, c13, c0, 3\n"
289 | "bic %0, %0, #3\n"
290 | : "=r"(__pthread_tsd));
291 | __pthread_tsd[slot] = val;
292 | #elif defined(__arm__) && !defined(_ARM_ARCH_6)
293 | register void **__pthread_tsd asm ("r9");
294 | __pthread_tsd[slot] = val;
295 | #endif
296 | return(0);
297 | }
298 | #elif defined(__ppc__) || defined(__ppc64__)
299 | /* To be used with static constant keys only */
300 | #define _pthread_setspecific_direct(key, val) pthread_setspecific(key, val)
301 | #else
302 | #error no pthread_setspecific_direct implementation for this arch
303 | #endif
304 |
305 | #endif /* TARGET_IPHONE_SIMULATOR */
306 |
307 | #define LOCK_INIT(l) ((l) = 0)
308 | #define LOCK_INITIALIZER 0
309 |
310 | #endif /* ! __ASSEMBLER__ */
311 | #endif /* _POSIX_PTHREAD_MACHDEP_H */
312 |
--------------------------------------------------------------------------------
/include/pthread_spinlock.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
3 | *
4 | * @APPLE_LICENSE_HEADER_START@
5 | *
6 | * This file contains Original Code and/or Modifications of Original Code
7 | * as defined in and that are subject to the Apple Public Source License
8 | * Version 2.0 (the 'License'). You may not use this file except in
9 | * compliance with the License. Please obtain a copy of the License at
10 | * http://www.opensource.apple.com/apsl/ and read it before using this
11 | * file.
12 | *
13 | * The Original Code and all software distributed under the License are
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 | * Please see the License for the specific language governing rights and
19 | * limitations under the License.
20 | *
21 | * @APPLE_LICENSE_HEADER_END@
22 | */
23 | /*
24 | * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
25 | * All Rights Reserved
26 | *
27 | * Permission to use, copy, modify, and distribute this software and
28 | * its documentation for any purpose and without fee is hereby granted,
29 | * provided that the above copyright notice appears in all copies and
30 | * that both the copyright notice and this permission notice appear in
31 | * supporting documentation.
32 | *
33 | * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
34 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
35 | * FOR A PARTICULAR PURPOSE.
36 | *
37 | * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
38 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
39 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
40 | * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
41 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
42 | *
43 | */
44 | /*
45 | * MkLinux
46 | */
47 |
48 | /*
49 | * POSIX Threads - IEEE 1003.1c
50 | */
51 |
52 | #ifndef _POSIX_PTHREAD_SPINLOCK_H
53 | #define _POSIX_PTHREAD_SPINLOCK_H
54 |
55 | #include
56 | #define __APPLE_API_PRIVATE
57 | #include
58 |
59 | #ifndef __POSIX_LIB__
60 | #define __POSIX_LIB__
61 | #endif
62 |
63 | #include "pthread_machdep.h" /* Machine-dependent definitions. */
64 |
65 | /* Number of times to spin when the lock is unavailable and we are on a
66 | multiprocessor. On a uniprocessor we yield the processor immediately. */
67 | #define MP_SPIN_TRIES 1000
68 | extern int _spin_tries;
69 | extern int __is_threaded;
70 |
71 | /* Internal mutex locks for data structures */
72 | #define TRY_LOCK(v) (!__is_threaded || _spin_lock_try((pthread_lock_t *)&(v)))
73 |
74 | /* _DO_SPINLOCK_LOCK() takes a (pthread_lock_t *) */
75 | #define _DO_SPINLOCK_LOCK(v) _spin_lock(v)
76 |
77 | /* _DO_SPINLOCK_UNLOCK() takes a (pthread_lock_t *) */
78 | #define _DO_SPINLOCK_UNLOCK(v) _spin_unlock(v)
79 |
80 | /* LOCK() takes a (pthread_lock_t) */
81 | #define LOCK(v) \
82 | do { \
83 | if (__is_threaded) { \
84 | _DO_SPINLOCK_LOCK((pthread_lock_t *)&(v)); \
85 | } \
86 | } while (0)
87 |
88 | /* UNLOCK() takes a (pthread_lock_t) */
89 | #define UNLOCK(v) \
90 | do { \
91 | if (__is_threaded) { \
92 | _DO_SPINLOCK_UNLOCK((pthread_lock_t *)&(v)); \
93 | } \
94 | } while (0)
95 |
96 | /* Prototypes. */
97 |
98 | /* Functions defined in machine-dependent files. */
99 | extern void _spin_lock(pthread_lock_t *lockp);
100 | extern int _spin_lock_try(pthread_lock_t *lockp);
101 | extern void _spin_unlock(pthread_lock_t *lockp);
102 |
103 | #endif /* _POSIX_PTHREAD_SPINLOCK_H */
104 |
--------------------------------------------------------------------------------
/include/pthread_spis.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2000-2011 Apple Computer, Inc. All rights reserved.
3 | *
4 | * @APPLE_LICENSE_HEADER_START@
5 | *
6 | * This file contains Original Code and/or Modifications of Original Code
7 | * as defined in and that are subject to the Apple Public Source License
8 | * Version 2.0 (the 'License'). You may not use this file except in
9 | * compliance with the License. Please obtain a copy of the License at
10 | * http://www.opensource.apple.com/apsl/ and read it before using this
11 | * file.
12 | *
13 | * The Original Code and all software distributed under the License are
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 | * Please see the License for the specific language governing rights and
19 | * limitations under the License.
20 | *
21 | * @APPLE_LICENSE_HEADER_END@
22 | */
23 | /*
24 | * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
25 | * All Rights Reserved
26 | *
27 | * Permission to use, copy, modify, and distribute this software and
28 | * its documentation for any purpose and without fee is hereby granted,
29 | * provided that the above copyright notice appears in all copies and
30 | * that both the copyright notice and this permission notice appear in
31 | * supporting documentation.
32 | *
33 | * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
34 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
35 | * FOR A PARTICULAR PURPOSE.
36 | *
37 | * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
38 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
39 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
40 | * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
41 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
42 | *
43 | */
44 | /*
45 | * MkLinux
46 | */
47 |
48 | /*
49 | * Extension SPIs.
50 | */
51 |
52 | #ifndef _PTHREAD_SPIS_H
53 | #define _PTHREAD_SPIS_H
54 |
55 |
56 | #include
57 |
58 | __BEGIN_DECLS
59 |
60 | #if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE)
61 | /* firstfit */
62 | #define PTHREAD_FIRSTFIT_MUTEX_INITIALIZER {_PTHREAD_FIRSTFIT_MUTEX_SIG_init, {0}}
63 | /*
64 | * Mutex attributes
65 | */
66 | #define _PTHREAD_MUTEX_POLICY_NONE 0
67 | #define _PTHREAD_MUTEX_POLICY_FAIRSHARE 1
68 | #define _PTHREAD_MUTEX_POLICY_FIRSTFIT 2
69 |
70 | /* sets the mutex policy attributes */
71 | int pthread_mutexattr_setpolicy_np(pthread_mutexattr_t *, int );
72 |
73 | #endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE */
74 |
75 | __END_DECLS
76 |
77 | #endif /* _PTHREAD_SPIS_H */
78 |
--------------------------------------------------------------------------------
/ldid.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Cydia Substrate - Powerful Code Insertion Platform
4 | # Copyright (C) 2008-2011 Jay Freeman (saurik)
5 |
6 | # GNU Lesser General Public License, Version 3 {{{
7 | #
8 | # Substrate is free software: you can redistribute it and/or modify it under
9 | # the terms of the GNU Lesser General Public License as published by the
10 | # Free Software Foundation, either version 3 of the License, or (at your
11 | # option) any later version.
12 | #
13 | # Substrate is distributed in the hope that it will be useful, but WITHOUT
14 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 | # License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with Substrate. If not, see .
20 | # }}}
21 |
22 | set -e
23 |
24 | file=$1
25 | shift 1
26 |
27 | archs=($(lipo -detailed_info "${file}" | grep '^architecture ' | cut -d ' ' -f 2))
28 |
29 | if [[ ${#archs[@]} == 0 ]]; then
30 | ldid -S "${file}"
31 | else
32 | files=()
33 |
34 | for arch in "${archs[@]}"; do
35 | lipo -extract "${arch}" "${file}" -output "${file}.${arch}"
36 | if [[ ${arch} == arm* ]]; then ldid -S "${file}.${arch}"; fi
37 | files[${#files[@]}]=${file}.${arch}
38 | done
39 |
40 | lipo -create "${files[@]}" -output "${file}"
41 | rm -f "${files[@]}"
42 | fi
43 |
--------------------------------------------------------------------------------
/package.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Cydia Substrate - Powerful Code Insertion Platform
4 | # Copyright (C) 2008-2011 Jay Freeman (saurik)
5 |
6 | # GNU Lesser General Public License, Version 3 {{{
7 | #
8 | # Substrate is free software: you can redistribute it and/or modify it under
9 | # the terms of the GNU Lesser General Public License as published by the
10 | # Free Software Foundation, either version 3 of the License, or (at your
11 | # option) any later version.
12 | #
13 | # Substrate is distributed in the hope that it will be useful, but WITHOUT
14 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 | # License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with Substrate. If not, see .
20 | # }}}
21 |
22 | set -e
23 |
24 | arch=$1
25 | shift 1
26 |
27 | pkg=package.${arch}
28 | sudo rm -rf "${pkg}"
29 |
30 | mkdir -p "${pkg}"/DEBIAN
31 | control=${pkg}/DEBIAN/control
32 | cat control."${arch}" >"${control}"
33 | ./control.sh >>"${control}"
34 |
35 | lib=/Library/MobileSubstrate
36 | mkdir -p "${pkg}/${lib}/DynamicLibraries"
37 |
38 | fwk=/Library/Frameworks/CydiaSubstrate.framework
39 |
40 | if [[ ${arch} == arm ]]; then
41 | rsc=${fwk}
42 | else
43 | rsc=${fwk}/Resources
44 | fi
45 |
46 | mkdir -p "${pkg}/${rsc}"
47 |
48 | for sub in Commands Headers Libraries; do
49 | mkdir -p "${pkg}/${fwk}/${sub}"
50 | done
51 |
52 | cp -a Info.plist "${pkg}/${rsc}/Info.plist"
53 | cp -a CydiaSubstrate.h "${pkg}/${fwk}/Headers"
54 |
55 | cp -a SubstrateBootstrap.dylib "${pkg}/${fwk}/Libraries"
56 | cp -a SubstrateLauncher.dylib "${pkg}/${fwk}/Libraries"
57 | cp -a SubstrateLoader.dylib "${pkg}/${fwk}/Libraries"
58 |
59 | cp -a libsubstrate.dylib "${pkg}/${fwk}/CydiaSubstrate"
60 |
61 | mkdir -p "${pkg}/usr/lib"
62 | ln -s libsubstrate.0.dylib "${pkg}/usr/lib/libsubstrate.dylib"
63 | ln -s "${fwk}/CydiaSubstrate" "${pkg}/usr/lib/libsubstrate.0.dylib"
64 |
65 | mkdir -p "${pkg}/usr/include"
66 | ln -s "${fwk}/Headers/CydiaSubstrate.h" "${pkg}/usr/include/substrate.h"
67 |
68 | mkdir -p "${pkg}/usr/bin"
69 |
70 | for cmd in cycc cynject; do
71 | ln -s "${fwk}/Commands/${cmd}" "${pkg}/usr/bin"
72 | cp -a "${cmd}" "${pkg}/${fwk}/Commands"
73 | done
74 |
75 | cp -a extrainst_ postrm "${pkg}/DEBIAN"
76 |
77 | if [[ ${arch} == arm ]]; then
78 | ln -s "${fwk}"/Libraries/SubstrateInjection.dylib "${pkg}/${lib}/MobileSubstrate.dylib"
79 |
80 | ln -s SubstrateBootstrap.dylib "${pkg}/${fwk}/Libraries/SubstrateInjection.dylib"
81 | else
82 | ln -s SubstrateLoader.dylib "${pkg}/${fwk}/Libraries/SubstrateInjection.dylib"
83 | fi
84 |
85 | function field() {
86 | grep ^"$1": "${control}" | cut -d ' ' -f 2
87 | }
88 |
89 | sudo chown -R root:staff "${pkg}"
90 |
91 | sudo chgrp procmod "${pkg}/${fwk}/Commands/cynject"
92 | sudo chmod g+s "${pkg}/${fwk}/Commands/cynject"
93 |
94 | #(cd "${pkg}" && find . -type f -o -type l)
95 | deb=$(field Package)_$(field Version)_$(field Architecture).deb
96 | dpkg-deb -b "${pkg}" "${deb}"
97 | ln -sf "${deb}" "$(field Package)_$(field Architecture).deb"
98 |
--------------------------------------------------------------------------------
/postrm.mm:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include
27 |
28 | #include
29 |
30 | #include "Cydia.hpp"
31 | #include "LaunchDaemons.hpp"
32 |
33 | int main(int argc, char *argv[]) {
34 | if (argc < 2 || (
35 | strcmp(argv[1], "abort-install") != 0 &&
36 | strcmp(argv[1], "remove") != 0 &&
37 | true)) return 0;
38 |
39 | NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
40 |
41 | NSFileManager *manager([NSFileManager defaultManager]);
42 | NSError *error;
43 |
44 | if (NSString *config = [NSString stringWithContentsOfFile:@ SubstrateLaunchConfig_ encoding:NSNonLossyASCIIStringEncoding error:&error]) {
45 | NSArray *lines([config componentsSeparatedByString:@"\n"]);
46 | NSMutableArray *copy([lines mutableCopy]);
47 |
48 | [copy removeObject:@""];
49 | [copy removeObject:@ SubstrateBootstrapExecute_];
50 |
51 | if ([copy count] == 0)
52 | [manager removeItemAtPath:@ SubstrateLaunchConfig_ error:&error];
53 | else {
54 | [copy addObject:@""];
55 |
56 | if (![copy isEqualToArray:lines])
57 | [[copy componentsJoinedByString:@"\n"] writeToFile:@ SubstrateLaunchConfig_ atomically:YES encoding:NSNonLossyASCIIStringEncoding error:&error];
58 | }
59 | }
60 |
61 | #ifdef __arm__
62 | if (MSClearLaunchDaemons())
63 | FinishCydia("reboot");
64 | #endif
65 |
66 | [pool release];
67 | return 0;
68 | }
69 |
--------------------------------------------------------------------------------
/safe.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | CYCC_APT_VERSION=$(./version.sh) cycc -i2.0 -s -p MobileSafety.mm
3 |
--------------------------------------------------------------------------------
/task_for_pid.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | com.apple.springboard.debugapplications
5 |
6 | get-task-allow
7 |
8 | task_for_pid-allow
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/trampoline.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Cydia Substrate - Powerful Code Insertion Platform
4 | # Copyright (C) 2008-2011 Jay Freeman (saurik)
5 |
6 | # GNU Lesser General Public License, Version 3 {{{
7 | #
8 | # Substrate is free software: you can redistribute it and/or modify it under
9 | # the terms of the GNU Lesser General Public License as published by the
10 | # Free Software Foundation, either version 3 of the License, or (at your
11 | # option) any later version.
12 | #
13 | # Substrate is distributed in the hope that it will be useful, but WITHOUT
14 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 | # License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with Substrate. If not, see .
20 | # }}}
21 |
22 | set -e
23 |
24 | shopt -s extglob
25 |
26 | hpp=$1
27 | object=$2
28 | name=$3
29 | sed=$4
30 | otool=$5
31 | lipo=$6
32 | nm=$7
33 | shift 7
34 |
35 | #shift 1
36 | #set /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2 -I/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.3.sdk/usr/include "$@"
37 |
38 | "$@"
39 |
40 | detailed=$("${lipo}" -detailed_info "${object}")
41 |
42 | {
43 |
44 | echo '#include "Trampoline.hpp"'
45 |
46 | for arch in $(echo "${detailed}" | "${sed}" -e '/^architecture / { s/^architecture //; p; }; d;'); do
47 | offset=$(echo "${detailed}" | "${sed}" -e '
48 | /^architecture / { x; s/.*/0/; x; };
49 | /^architecture '${arch}'$/ { x; s/.*/1/; x; };
50 | x; /^1$/ { x; /^ *offset / { s/^ *offset //; p; }; x; }; x;
51 | d;
52 | ')
53 |
54 | file=($("${otool}" -arch "${arch}" -l "${object}" | "${sed}" -e '
55 | x; /^1$/ { x;
56 | /^ *fileoff / { s/^.* //; p; };
57 | /^ *filesize / { s/^.* //; p; };
58 | x; }; x;
59 |
60 | /^ *cmd LC_SEGMENT/ { x; s/.*/1/; x; };
61 |
62 | d;
63 | '))
64 |
65 | fileoff=${file[0]}
66 | filesize=${file[1]}
67 |
68 | echo
69 | echo "static const char ${name}_${arch}_data_[] = {"
70 |
71 | od -v -t x1 -t c -j "$((offset + fileoff))" -N "${filesize}" "${object}" | "${sed}" -e '
72 | /^[0-7]/ ! {
73 | s@^ @// @;
74 | s/\(....\)/ \1/g;
75 | s@^ // @//@;
76 | s/ *$/,/;
77 | };
78 |
79 | /^[0-7]/ {
80 | s/^[^ ]*//;
81 | s/ */ /g;
82 | s/^ *//;
83 | s/ $//;
84 | s/ /,/g;
85 | s/\([^,][^,]\)/0x\1/g;
86 | s/$/,/;
87 | /^,$/ ! { s/^/ /g; p; }; d;
88 | };
89 | '
90 |
91 | echo "};"
92 |
93 | echo
94 | entry=$("${nm}" -arch "${arch}" "${object}" | "${sed}" -e '/ _Start$/ { s/ .*//; p; }; d;')
95 | entry=${entry##*(0)}
96 | echo "static size_t ${name}_${arch}_entry_ = 0x${entry:=0};"
97 |
98 | echo
99 | echo "/*"
100 | "${otool}" -vVt -arch "${arch}" "${object}"
101 | echo "*/"
102 |
103 | echo
104 | echo "static Trampoline ${name}_${arch}_ = {"
105 | echo " ${name}_${arch}_data_,"
106 | echo " sizeof(${name}_${arch}_data_),"
107 | echo " ${name}_${arch}_entry_,"
108 | echo "};"
109 | done
110 |
111 | } >"${hpp}"
112 |
113 | #rm -f "${object}"
114 |
--------------------------------------------------------------------------------
/version.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | git describe --tags --dirty="+" --match="v*" | sed -e 's@-\([^-]*\)-\([^-]*\)$@+\1.\2@;s@^v@@'
3 |
--------------------------------------------------------------------------------
/x86.hpp:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2011 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #ifndef SUBSTRATE_X86_HPP
23 | #define SUBSTRATE_X86_HPP
24 |
25 | #include "Buffer.hpp"
26 |
27 | #ifdef __LP64__
28 | static const bool ia32 = false;
29 | #else
30 | static const bool ia32 = true;
31 | #endif
32 |
33 | enum I$r {
34 | I$rax, I$rcx, I$rdx, I$rbx,
35 | I$rsp, I$rbp, I$rsi, I$rdi,
36 | I$r8, I$r9, I$r10, I$r11,
37 | I$r12, I$r13, I$r14, I$r15,
38 | };
39 |
40 | _disused static bool MSIs32BitOffset(uintptr_t target, uintptr_t source) {
41 | intptr_t offset(target - source);
42 | return int32_t(offset) == offset;
43 | }
44 |
45 | _disused static size_t MSSizeOfSkip() {
46 | return 5;
47 | }
48 |
49 | _disused static size_t MSSizeOfPushPointer(uintptr_t target) {
50 | return uint64_t(target) >> 32 == 0 ? 5 : 13;
51 | }
52 |
53 | _disused static size_t MSSizeOfPushPointer(void *target) {
54 | return MSSizeOfPushPointer(reinterpret_cast(target));
55 | }
56 |
57 | _disused static size_t MSSizeOfJump(bool blind, uintptr_t target, uintptr_t source = 0) {
58 | if (ia32 || !blind && MSIs32BitOffset(target, source + 5))
59 | return MSSizeOfSkip();
60 | else
61 | return MSSizeOfPushPointer(target) + 1;
62 | }
63 |
64 | _disused static size_t MSSizeOfJump(uintptr_t target, uintptr_t source) {
65 | return MSSizeOfJump(false, target, source);
66 | }
67 |
68 | _disused static size_t MSSizeOfJump(uintptr_t target) {
69 | return MSSizeOfJump(true, target);
70 | }
71 |
72 | _disused static size_t MSSizeOfJump(void *target, void *source) {
73 | return MSSizeOfJump(reinterpret_cast(target), reinterpret_cast(source));
74 | }
75 |
76 | _disused static size_t MSSizeOfJump(void *target) {
77 | return MSSizeOfJump(reinterpret_cast(target));
78 | }
79 |
80 | _disused static void MSWriteSkip(uint8_t *¤t, ssize_t size) {
81 | MSWrite(current, 0xe9);
82 | MSWrite(current, size);
83 | }
84 |
85 | _disused static void MSPushPointer(uint8_t *¤t, uintptr_t target) {
86 | MSWrite(current, 0x68);
87 | MSWrite(current, target);
88 |
89 | if (uint32_t high = uint64_t(target) >> 32) {
90 | MSWrite(current, 0xc7);
91 | MSWrite(current, 0x44);
92 | MSWrite(current, 0x24);
93 | MSWrite(current, 0x04);
94 | MSWrite(current, high);
95 | }
96 | }
97 |
98 | _disused static void MSPushPointer(uint8_t *¤t, void *target) {
99 | return MSPushPointer(current, reinterpret_cast(target));
100 | }
101 |
102 | _disused static void MSWriteCall(uint8_t *¤t, I$r target) {
103 | if (target >> 3 != 0)
104 | MSWrite(current, 0x40 | (target & 0x08) >> 3);
105 | MSWrite(current, 0xff);
106 | MSWrite(current, 0xd0 | target & 0x07);
107 | }
108 |
109 | _disused static void MSWriteCall(uint8_t *¤t, uintptr_t target) {
110 | uintptr_t source(reinterpret_cast(current));
111 |
112 | if (ia32 || MSIs32BitOffset(target, source + 5)) {
113 | MSWrite(current, 0xe8);
114 | MSWrite(current, target - (source + 5));
115 | } else {
116 | MSPushPointer(current, target);
117 |
118 | MSWrite(current, 0x83);
119 | MSWrite(current, 0xc4);
120 | MSWrite(current, 0x08);
121 |
122 | MSWrite(current, 0x67);
123 | MSWrite(current, 0xff);
124 | MSWrite(current, 0x54);
125 | MSWrite(current, 0x24);
126 | MSWrite(current, 0xf8);
127 | }
128 | }
129 |
130 | template
131 | _disused static void MSWriteCall(uint8_t *¤t, Type_ *target) {
132 | return MSWriteCall(current, reinterpret_cast(target));
133 | }
134 |
135 | _disused static void MSWriteJump(uint8_t *¤t, uintptr_t target) {
136 | uintptr_t source(reinterpret_cast(current));
137 |
138 | if (ia32 || MSIs32BitOffset(target, source + 5))
139 | MSWriteSkip(current, target - (source + 5));
140 | else {
141 | MSPushPointer(current, target);
142 | MSWrite(current, 0xc3);
143 | }
144 | }
145 |
146 | _disused static void MSWriteJump(uint8_t *¤t, void *target) {
147 | return MSWriteJump(current, reinterpret_cast(target));
148 | }
149 |
150 | _disused static void MSWriteJump(uint8_t *¤t, I$r target) {
151 | if (target >> 3 != 0)
152 | MSWrite(current, 0x40 | (target & 0x08) >> 3);
153 | MSWrite(current, 0xff);
154 | MSWrite(current, 0xe0 | target & 0x07);
155 | }
156 |
157 | _disused static void MSWritePop(uint8_t *¤t, uint8_t target) {
158 | if (target >> 3 != 0)
159 | MSWrite(current, 0x40 | (target & 0x08) >> 3);
160 | MSWrite(current, 0x58 | target & 0x07);
161 | }
162 |
163 | _disused static size_t MSSizeOfPop(uint8_t target) {
164 | return target >> 3 != 0 ? 2 : 1;
165 | }
166 |
167 | _disused static void MSWritePush(uint8_t *¤t, I$r target) {
168 | if (target >> 3 != 0)
169 | MSWrite(current, 0x40 | (target & 0x08) >> 3);
170 | MSWrite(current, 0x50 | target & 0x07);
171 | }
172 |
173 | _disused static void MSWriteAdd(uint8_t *¤t, I$r target, uint8_t source) {
174 | MSWrite(current, 0x83);
175 | MSWrite(current, 0xc4 | target & 0x07);
176 | MSWrite(current, source);
177 | }
178 |
179 | _disused static void MSWriteSet64(uint8_t *¤t, I$r target, uintptr_t source) {
180 | MSWrite(current, 0x48 | (target & 0x08) >> 3 << 2);
181 | MSWrite(current, 0xb8 | target & 0x7);
182 | MSWrite(current, source);
183 | }
184 |
185 | template
186 | _disused static void MSWriteSet64(uint8_t *¤t, I$r target, Type_ *source) {
187 | return MSWriteSet64(current, target, reinterpret_cast(source));
188 | }
189 |
190 | _disused static void MSWriteMove64(uint8_t *¤t, uint8_t source, uint8_t target) {
191 | MSWrite(current, 0x48 | (target & 0x08) >> 3 << 2 | (source & 0x08) >> 3);
192 | MSWrite(current, 0x8b);
193 | MSWrite(current, (target & 0x07) << 3 | source & 0x07);
194 | }
195 |
196 | _disused static size_t MSSizeOfMove64() {
197 | return 3;
198 | }
199 |
200 | #endif//SUBSTRATE_X86_HPP
201 |
--------------------------------------------------------------------------------