Welcome to mirror list, hosted at ThFree Co, Russian Federation.

mach_inject_bundle_stub.c « mach_inject_bundle_stub - github.com/mumble-voip/mach_override.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 9de382c7039766c46d76948197a52ba8518073fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*******************************************************************************
	mach_inject_bundle_stub.c
		Copyright (c) 2003-2009 Jonathan 'Wolf' Rentzsch: <http://rentzsch.com>
		Some rights reserved: <http://opensource.org/licenses/mit-license.php>
		
	Design inspired by SCPatchLoader, by Jon Gotow of St. Clair Software:
		<http://www.stclairsoft.com>

	***************************************************************************/

#include "mach_inject_bundle_stub.h"
#include "load_bundle.h"
#include "mach_inject.h" // for INJECT_ENTRY

#include <assert.h>
#include <mach/mach_init.h>
#include <mach/thread_act.h>
#include <pthread.h>
#include <Carbon/Carbon.h>

/**************************
*	
*	Funky Protos
*	
**************************/
#pragma mark	(Funky Protos)

	void
INJECT_ENTRY(
		ptrdiff_t						codeOffset,
		mach_inject_bundle_stub_param	*param,
		size_t							paramSize,
		char							*dummy_pthread_struc );
		
	void*
pthread_entry(
		mach_inject_bundle_stub_param	*param );
	
	pascal
	void
EventLoopTimerEntry(
		EventLoopTimerRef				inTimer,
		mach_inject_bundle_stub_param	*param );

/*******************************************************************************
*	
*	Implementation
*	
*******************************************************************************/
#pragma mark	-
#pragma mark	(Implementation)

	void
INJECT_ENTRY(
		ptrdiff_t						codeOffset,
		mach_inject_bundle_stub_param	*param,
		size_t							paramSize,
		char							*dummy_pthread_struct )
{
	assert( param );
	
	param->codeOffset = codeOffset;
	
#if defined (__i386__) || defined(__x86_64__)
	// On intel, per-pthread data is a zone of data that must be allocated.
	// if not, all function trying to access per-pthread data (all mig functions for instance)
	// will crash. 
	extern void __pthread_set_self(char*);
	__pthread_set_self(dummy_pthread_struct);
#endif

	fprintf(stderr, "mach_inject_bundle: entered in %s, codeOffset: %td, param: %p, paramSize: %lu\n",
			INJECT_ENTRY_SYMBOL, codeOffset, param, paramSize);

	pthread_attr_t attr;
	pthread_attr_init(&attr); 
	
	int policy;
	pthread_attr_getschedpolicy( &attr, &policy );
	pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
	pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
	
	struct sched_param sched;
	sched.sched_priority = sched_get_priority_max( policy );
	pthread_attr_setschedparam( &attr, &sched );
	
	pthread_t thread;
	pthread_create( &thread,
					&attr,
					(void* (*)(void*))((long)pthread_entry + codeOffset),
					(void*) param );
	pthread_attr_destroy(&attr);
	
	thread_suspend(mach_thread_self());
}

	void*
pthread_entry(
		mach_inject_bundle_stub_param	*param )
{
	fprintf(stderr, "mach_inject_bundle: entered in pthread_entry, param: %p\n", param);
	assert( param );
	
	EventLoopTimerProcPtr proc = (EventLoopTimerProcPtr) EventLoopTimerEntry;
	proc += param->codeOffset;
	EventLoopTimerUPP upp = NewEventLoopTimerUPP( proc );
	
	InstallEventLoopTimer( GetMainEventLoop(), 0, 0, upp, (void*)param, NULL );
	return NULL;
}

	pascal
	void
EventLoopTimerEntry(
		EventLoopTimerRef				inTimer,
		mach_inject_bundle_stub_param	*param )
{
	fprintf(stderr, "mach_inject_bundle: entered in EventLoopTimerEntry, inTimer: %p, param: %p\n", inTimer, param);
	assert( inTimer );
	assert( param );
	load_bundle_package( param->bundlePackageFileSystemRepresentation );
}