-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlocalUtil_xnu.c
executable file
·144 lines (125 loc) · 3.8 KB
/
localUtil_xnu.c
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <mach-o/loader.h>
#include <mach-o/getsect.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <pwd.h>
#include <string.h>
#include "localUtil.h"
#include "localUtil_xnu.h"
#define SUPER_APPLE_MCGHEE 1
int getsegbynamefromheader_64(struct mach_header_64* mach_header_tmp, const char* name, struct segment_command_64** seg_out)
{
int result = -1;
int cmd_index = 0;
struct load_command* lc_iter = (struct load_command*)&mach_header_tmp[1];
struct segment_command_64* seg_tmp = 0;
for (; cmd_index < mach_header_tmp->ncmds; cmd_index++)
{
if (lc_iter->cmd == LC_SEGMENT_64)
{
seg_tmp = (struct segment_command_64*)lc_iter;
FINISH_IF(strcmp(seg_tmp->segname, name) == 0);
}
lc_iter = (struct load_command*)((size_t)lc_iter + lc_iter->cmdsize);
}
goto fail;
finish:
result = 0;
if (seg_out != 0)
{
*seg_out = (struct segment_command_64*)lc_iter;
}
fail:
return result;
}
int getloadcommandfrommach(struct mach_header_64* mach_header_tmp, uint32_t lc_targ, struct load_command** lc_res)
{
int result = -1;
int cmd_index = 0;
struct load_command* lc_iter = (struct load_command*)&mach_header_tmp[1];
for (; cmd_index < mach_header_tmp->ncmds; cmd_index++)
{
FINISH_IF(lc_iter->cmd == lc_targ);
lc_iter = (struct load_command*)((size_t)lc_iter + lc_iter->cmdsize);
}
goto fail;
finish:
result = 0;
if (lc_res != 0)
{
*lc_res = lc_iter;
}
fail:
return result;
}
int getpidbyname(const char* proc_name, pid_t* pid_out)
{
int result = -1;
struct kinfo_proc *proc_list = NULL;
size_t length = 0;
int proc_count = 0;
int proc_iter = 0;
const char* proc_name_iter = 0;
static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
// Call sysctl with a NULL buffer to get proper length
SAFE_BAIL(sysctl((int *)name, (sizeof(name) / sizeof(*name)) - 1, NULL, &length, NULL, 0) != 0);
// Allocate buffer
proc_list = malloc(length);
SAFE_BAIL(proc_list == 0);
// Get the actual process list
SAFE_BAIL(sysctl((int *)name, (sizeof(name) / sizeof(*name)) - 1, proc_list, &length, NULL, 0) != 0);
proc_count = length / sizeof(struct kinfo_proc);
// use getpwuid_r() if you want to be thread-safe
for (proc_iter = 0; proc_iter < proc_count; proc_iter++)
{
proc_name_iter = proc_list[proc_iter].kp_proc.p_comm;
if (strcmp(proc_name_iter, proc_name) == 0)
{
goto finish;
}
}
goto fail;
finish:
result = 0;
if (pid_out != 0)
{
*pid_out = proc_list[proc_iter].kp_proc.p_pid;
}
fail:
SAFE_FREE(proc_list);
return result;
}
int section_with_sym(struct mach_header_64* mach_header_tmp, size_t sym_address, struct section_64** section_64_out)
{
int result = -1;
int cmd_index = 0;
int sec_index = 0;
struct load_command* lc_iter = (struct load_command*)&mach_header_tmp[1];
struct segment_command_64* lc_seg_tmp = 0;
struct section_64* lc_sec_tmp = 0;
for (; cmd_index < mach_header_tmp->ncmds; cmd_index++)
{
if (lc_iter->cmd == LC_SEGMENT_64)
{
lc_seg_tmp = (struct segment_command_64*)lc_iter;
lc_sec_tmp = (struct section_64*)&lc_seg_tmp[1];
for(sec_index = 0; sec_index < lc_seg_tmp->nsects; sec_index++, lc_sec_tmp++)
{
FINISH_IF(REGION_CONTAINS(lc_sec_tmp->addr, lc_sec_tmp->size, sym_address));
}
}
lc_iter = (struct load_command*)((size_t)lc_iter + lc_iter->cmdsize);
}
goto fail;
finish:
result = 0;
if (section_64_out != 0)
{
*section_64_out = lc_sec_tmp;
}
fail:
return result;
}