Skip to content
This repository was archived by the owner on Mar 11, 2024. It is now read-only.

Commit 65f4dc6

Browse files
committed
Inject Generics until Swift 4.1
1 parent dc52074 commit 65f4dc6

28 files changed

+2326
-79
lines changed

Bootstrap/Info.plist

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>CFBundleDevelopmentRegion</key>
6+
<string>$(DEVELOPMENT_LANGUAGE)</string>
7+
<key>CFBundleExecutable</key>
8+
<string>$(EXECUTABLE_NAME)</string>
9+
<key>CFBundleIdentifier</key>
10+
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11+
<key>CFBundleInfoDictionaryVersion</key>
12+
<string>6.0</string>
13+
<key>CFBundleName</key>
14+
<string>$(PRODUCT_NAME)</string>
15+
<key>CFBundlePackageType</key>
16+
<string>BNDL</string>
17+
<key>CFBundleShortVersionString</key>
18+
<string>1.0</string>
19+
<key>CFBundleVersion</key>
20+
<string>1</string>
21+
<key>NSHumanReadableCopyright</key>
22+
<string>Copyright © 2017 John Holdsworth. All rights reserved.</string>
23+
<key>NSPrincipalClass</key>
24+
<string></string>
25+
</dict>
26+
</plist>

Bootstrap/mach_inject_bundle_stub.c

+141
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
// mach_inject_bundle_stub.c semver:1.2.0
2+
// Copyright (c) 2003-2012 Jonathan 'Wolf' Rentzsch: http://rentzsch.com
3+
// Some rights reserved: http://opensource.org/licenses/mit
4+
// https://github.com/rentzsch/mach_inject
5+
//
6+
// Design inspired by SCPatchLoader by Jon Gotow of St. Clair Software:
7+
// http://www.stclairsoft.com
8+
9+
#include "mach_inject_bundle_stub.h"
10+
#include "mach_inject.h" // for INJECT_ENTRY
11+
12+
#include <assert.h>
13+
#include <mach/mach_init.h>
14+
#include <mach/thread_act.h>
15+
#include <pthread.h>
16+
#include <dlfcn.h>
17+
18+
#include <sys/mman.h>
19+
#include <sys/stat.h>
20+
#include <unistd.h>
21+
#include <fcntl.h>
22+
23+
/**************************
24+
*
25+
* Funky Protos
26+
*
27+
**************************/
28+
#pragma mark (Funky Protos)
29+
30+
void
31+
INJECT_ENTRY(
32+
ptrdiff_t codeOffset,
33+
mach_inject_bundle_stub_param *param,
34+
size_t paramSize,
35+
char *dummy_pthread_struc );
36+
37+
void*
38+
pthread_entry(
39+
mach_inject_bundle_stub_param *param );
40+
41+
42+
/*******************************************************************************
43+
*
44+
* Implementation
45+
*
46+
*******************************************************************************/
47+
#pragma mark -
48+
#pragma mark (Implementation)
49+
50+
void
51+
INJECT_ENTRY(
52+
ptrdiff_t codeOffset,
53+
mach_inject_bundle_stub_param *param,
54+
size_t paramSize,
55+
char *dummy_pthread_struct )
56+
{
57+
assert( param );
58+
59+
#if defined (__i386__) || defined(__x86_64__)
60+
// On intel, per-pthread data is a zone of data that must be allocated.
61+
// if not, all function trying to access per-pthread data (all mig functions for instance)
62+
// will crash.
63+
extern void _pthread_set_self(char*);
64+
_pthread_set_self(dummy_pthread_struct);
65+
#endif
66+
67+
// fprintf(stderr, "mach_inject_bundle: entered in %s, codeOffset: %td, param: %p, paramSize: %lu\n",
68+
// INJECT_ENTRY_SYMBOL, codeOffset, param, paramSize);
69+
70+
pthread_attr_t attr;
71+
pthread_attr_init(&attr);
72+
73+
int policy;
74+
pthread_attr_getschedpolicy( &attr, &policy );
75+
pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
76+
pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
77+
78+
struct sched_param sched;
79+
sched.sched_priority = sched_get_priority_max( policy );
80+
pthread_attr_setschedparam( &attr, &sched );
81+
82+
pthread_t thread;
83+
pthread_create( &thread,
84+
&attr,
85+
(void* (*)(void*))((long)pthread_entry + codeOffset),
86+
(void*) param );
87+
pthread_attr_destroy(&attr);
88+
89+
thread_suspend(mach_thread_self());
90+
}
91+
92+
void*
93+
pthread_entry(
94+
mach_inject_bundle_stub_param *param ) {
95+
96+
// The following descent into dark magic is brought to you by:
97+
// https://en.wikipedia.org/wiki/Address_space_layout_randomization
98+
//
99+
// As a start, the first page actually loaded into memory is located.
100+
// Shortly after this page will be "libdyld" which is itself a dylib.
101+
// Which page is found using a offset determined in the Helper using "nm"
102+
// in confunction with the first 16 bytes of the dlopen() machine code
103+
// which seems to be shared across tested iOS versions (8.4 -> 10.0.)
104+
//
105+
// Move along, nothing to see here...
106+
107+
#define VALID_ADDRESS( _addr ) (mincore( _addr, PAGE_SIZE, vec ) == 0 && vec[0] & MINCORE_INCORE)
108+
109+
char *loadAddress = (char *)0x100000000, vec[1];
110+
while ( !VALID_ADDRESS( loadAddress ) )
111+
loadAddress += PAGE_SIZE;
112+
113+
static unsigned char dlopenInstrux[] = {
114+
0x55, 0x48, 0x89, 0xe5, 0x41, 0x56, 0x53, 0x41,
115+
0x89, 0xf6, 0x48, 0x89, 0xfb, 0x48};
116+
typedef void * (*dlopen_f)(const char * __path, int __mode);
117+
dlopen_f dlopen_ = NULL;
118+
119+
for ( ; loadAddress < (char *)0x200000000 && VALID_ADDRESS( loadAddress ) ; loadAddress += PAGE_SIZE )
120+
if (memcmp(loadAddress + param->dlopenPageOffset, dlopenInstrux, sizeof dlopenInstrux) == 0) {
121+
dlopen_ = (dlopen_f)(loadAddress + param->dlopenPageOffset);
122+
break;
123+
}
124+
125+
const char *error = NULL;
126+
127+
if (!dlopen_)
128+
error = "Could not locate dlopen()";
129+
else if ( dlopen_(param->bundleExecutableFileSystemRepresentation, RTLD_NOW) == NULL )
130+
error = ((const char *(*)(void))(loadAddress + param->dlerrorPageOffset))();
131+
132+
if (error) {
133+
int log = open(HELPER_LOGFILE, O_CREAT|O_WRONLY|O_APPEND, 0666);
134+
write(log, error, strlen(error));
135+
write(log, "\n", 1);
136+
close(log);
137+
}
138+
139+
return NULL;
140+
}
141+

Bootstrap/mach_inject_bundle_stub.h

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// mach_inject_bundle_stub.h semver:1.2.0
2+
// Copyright (c) 2003-2012 Jonathan 'Wolf' Rentzsch: http://rentzsch.com
3+
// Some rights reserved: http://opensource.org/licenses/mit
4+
// https://github.com/rentzsch/mach_inject
5+
//
6+
// Design inspired by SCPatchLoader by Jon Gotow of St. Clair Software:
7+
// http://www.stclairsoft.com
8+
9+
#ifndef _mach_inject_bundle_stub_
10+
#define _mach_inject_bundle_stub_
11+
12+
#define HELPER_LOGFILE "/tmp/helper.log"
13+
14+
typedef struct {
15+
unsigned dlopenPageOffset, dlerrorPageOffset;
16+
char bundleExecutableFileSystemRepresentation[1];
17+
} mach_inject_bundle_stub_param;
18+
19+
#endif // _mach_inject_bundle_stub_

DDHotKey/DDHotKeyCenter.h

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
DDHotKey -- DDHotKeyCenter.h
3+
4+
Copyright (c) Dave DeLong <http://www.davedelong.com>
5+
6+
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
7+
8+
The software is provided "as is", without warranty of any kind, including all implied warranties of merchantability and fitness. In no event shall the author(s) or copyright holder(s) be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.
9+
*/
10+
11+
#import <Cocoa/Cocoa.h>
12+
13+
//a convenient typedef for the required signature of a hotkey block callback
14+
typedef void (^DDHotKeyTask)(NSEvent*);
15+
16+
@interface DDHotKey : NSObject
17+
18+
// creates a new hotkey but does not register it
19+
+ (instancetype)hotKeyWithKeyCode:(unsigned short)keyCode modifierFlags:(NSUInteger)flags task:(DDHotKeyTask)task;
20+
21+
@property (nonatomic, assign, readonly) id target;
22+
@property (nonatomic, readonly) SEL action;
23+
@property (nonatomic, strong, readonly) id object;
24+
@property (nonatomic, copy, readonly) DDHotKeyTask task;
25+
26+
@property (nonatomic, readonly) unsigned short keyCode;
27+
@property (nonatomic, readonly) NSUInteger modifierFlags;
28+
29+
@end
30+
31+
#pragma mark -
32+
33+
@interface DDHotKeyCenter : NSObject
34+
35+
+ (instancetype)sharedHotKeyCenter;
36+
37+
/**
38+
Register a hotkey.
39+
*/
40+
- (DDHotKey *)registerHotKey:(DDHotKey *)hotKey;
41+
42+
/**
43+
Register a target/action hotkey.
44+
The modifierFlags must be a bitwise OR of NSCommandKeyMask, NSAlternateKeyMask, NSControlKeyMask, or NSShiftKeyMask;
45+
Returns the hotkey registered. If registration failed, returns nil.
46+
*/
47+
- (DDHotKey *)registerHotKeyWithKeyCode:(unsigned short)keyCode modifierFlags:(NSUInteger)flags target:(id)target action:(SEL)action object:(id)object;
48+
49+
/**
50+
Register a block callback hotkey.
51+
The modifierFlags must be a bitwise OR of NSCommandKeyMask, NSAlternateKeyMask, NSControlKeyMask, or NSShiftKeyMask;
52+
Returns the hotkey registered. If registration failed, returns nil.
53+
*/
54+
- (DDHotKey *)registerHotKeyWithKeyCode:(unsigned short)keyCode modifierFlags:(NSUInteger)flags task:(DDHotKeyTask)task;
55+
56+
/**
57+
See if a hotkey exists with the specified keycode and modifier flags.
58+
NOTE: this will only check among hotkeys you have explicitly registered with DDHotKeyCenter. This does not check all globally registered hotkeys.
59+
*/
60+
- (BOOL)hasRegisteredHotKeyWithKeyCode:(unsigned short)keyCode modifierFlags:(NSUInteger)flags;
61+
62+
/**
63+
Unregister a specific hotkey
64+
*/
65+
- (void)unregisterHotKey:(DDHotKey *)hotKey;
66+
67+
/**
68+
Unregister all hotkeys
69+
*/
70+
- (void)unregisterAllHotKeys;
71+
72+
/**
73+
Unregister all hotkeys with a specific target
74+
*/
75+
- (void)unregisterHotKeysWithTarget:(id)target;
76+
77+
/**
78+
Unregister all hotkeys with a specific target and action
79+
*/
80+
- (void)unregisterHotKeysWithTarget:(id)target action:(SEL)action;
81+
82+
/**
83+
Unregister a hotkey with a specific keycode and modifier flags
84+
*/
85+
- (void)unregisterHotKeyWithKeyCode:(unsigned short)keyCode modifierFlags:(NSUInteger)flags;
86+
87+
/**
88+
Returns a set of currently registered hotkeys
89+
**/
90+
- (NSSet *)registeredHotKeys;
91+
92+
@end
93+

0 commit comments

Comments
 (0)