Chameleon

Chameleon Svn Source Tree

Root/tags/2.3/i386/util/dyldsymboltool.c

Source at commit HEAD created 2 years 11 months ago.
By ifabio, Few update to kernelPatcher (Credits to CrazyBirdy)
1/*
2 * Copyright (c) 2010-2015 Evan Lojewski. All rights reserved.
3 *
4 *dyldsymboltool
5 *
6 *Generates a dylib file for the dyld implimentation in chameleon
7 *to load and link. This is used to import the boot symbols into the
8 *module system.
9 */
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <mach/mach.h>
14#include <sys/file.h>
15#include <mach-o/loader.h>
16#include <mach-o/nlist.h>
17
18
19#define DYLIB_NAME "Symbols"
20#define VOID_SYMBOL "_load_all_modules"
21#define START_SYMBOL "start"
22
23typedef struct symbols_dylib
24{
25struct mach_headerheader;
26struct dylib_commanddylib_info;
27charmodule_name[sizeof(DYLIB_NAME)];
28struct symtab_commandsymtab;
29} symbols_dylib_t;
30
31
32typedef struct symbolList_t
33{
34char*name;
35uint32_taddr;
36intpos;
37struct symbolList_t*next;
38} symbolList_t;
39
40
41int num_symbols(symbolList_t* list);
42int string_size(symbolList_t* list);
43void add_symbol(symbolList_t** list, char* name, uint32_t addr);
44
45
46int main(int argc, char *argv[])
47{
48if(argc < 3)
49{
50fprintf(stderr, "usage: dyldsymboltool obj1 [obj2 ...] outfile\n");
51
52exit(-1);
53}
54
55
56
57symbols_dylib_t dylib;
58symbolList_t*symbols = NULL;
59
60uint32_t start_addr = 0;
61
62
63
64
65 int i;
66for(i = 1; i < argc-1; i++)
67 {
68 char line[256];
69 char* command = malloc(strlen(argv[1]) + sizeof("nm -g "));
70 FILE *fpipe;
71
72 // Parse boot.sys (arg1) to get symtab
73 sprintf(command, "nm -g %s", argv[i]);// TODO: read boot.sym directly, no need for nm
74
75 if ( !(fpipe = (FILE*)popen(command,"r")) )
76 { // If fpipe is NULL
77 perror("Problems with pipe");
78 exit(1);
79 }
80
81
82 while ( fgets( line, sizeof line, fpipe))
83 {
84 if((strlen(line) < strlen(argv[i]) ||
85 strncmp(line, argv[i], strlen(argv[i])) != 0)
86 && line[0] != ' ')
87 {
88 uint32_t address = 0;
89 char* addr = strtok(line, " ");
90 strtok(NULL, " ");
91 char* name = strtok(NULL, " ");
92 name[strlen(name)-1] = 0;// remove newline
93 sscanf(addr, "%x", &address);
94 if(strcmp(name, VOID_SYMBOL) == 0)
95{
96start_addr = address;
97}
98if(strcmp(name, START_SYMBOL) == 0)
99{
100if(!start_addr) start_addr = address;
101}
102 else add_symbol(&symbols, name, address);
103 }
104 }
105
106 pclose(fpipe);
107
108 free(command);
109 }
110
111
112
113if(start_addr == 0)
114{
115fprintf(stderr, "Unable to locate Symbol.dylib start function\n");
116
117 //exit(1);
118}
119else
120{
121add_symbol(&symbols, START_SYMBOL, start_addr);
122}
123
124/* Header command info */
125dylib.header.ncmds = 2;
126dylib.header.sizeofcmds = sizeof(dylib) - sizeof(struct mach_header);// + dylib.symtab.nsyms * sizeof(struct nlist) + dylib.symtab.strsize;
127
128dylib.header.magic = MH_MAGIC;
129dylib.header.cputype = CPU_TYPE_X86;
130dylib.header.cpusubtype = /*CPUSUBTYPE_I386*/ 3;
131dylib.header.filetype = MH_DYLIB;
132dylib.header.flags = MH_NOUNDEFS | MH_DYLDLINK | MH_NO_REEXPORTED_DYLIBS;
133
134/* Load Commands - dylib id */
135dylib.dylib_info.cmd = LC_ID_DYLIB;
136dylib.dylib_info.cmdsize = sizeof(struct dylib_command) + sizeof(dylib.module_name);// todo: verify
137dylib.dylib_info.dylib.name.offset = sizeof(struct dylib_command);
138dylib.dylib_info.dylib.timestamp = 0;// TODO: populate with time
139dylib.dylib_info.dylib.current_version = 0;// TODO
140dylib.dylib_info.dylib.compatibility_version = 0;// TODO
141
142
143//int offset = dylib.dylib_info.cmdsize%4 ? 4 - (dylib.dylib_info.cmdsize % 4) : 0;
144//dylib.dylib_info.cmdsize += offset;
145//dylib.header.sizeofcmds += offset;
146
147strcpy(dylib.module_name, DYLIB_NAME);
148
149/* Load Commands - Symtable */
150dylib.symtab.cmd = LC_SYMTAB;
151dylib.symtab.symoff = sizeof(dylib);
152dylib.symtab.nsyms = num_symbols(symbols);
153dylib.symtab.stroff = sizeof(dylib) + dylib.symtab.nsyms * sizeof(struct nlist);
154dylib.symtab.strsize = string_size(symbols);
155dylib.symtab.cmdsize = sizeof(struct symtab_command);
156
157
158FILE *outfile = fopen(argv[argc-1], "w");
159fwrite(&dylib,sizeof(dylib)/* Sizeof header + module name */
160, 1, outfile);
161
162char *symtab = malloc(dylib.symtab.stroff + dylib.symtab.strsize - sizeof(dylib) + 1); // Add extra 1 for last symbol
163bzero(symtab, dylib.symtab.nsyms * sizeof(struct nlist) + dylib.symtab.strsize + 1);
164char *orig = symtab;
165
166//symtab += offset;
167
168
169while(symbols)
170{
171
172((struct nlist*)symtab)->n_un.n_strx = symbols->pos;
173((struct nlist*)symtab)->n_type = 0xF;// TODO: read from boot.sys
174((struct nlist*)symtab)->n_sect = 0;
175((struct nlist*)symtab)->n_desc = REFERENCE_FLAG_DEFINED;
176((struct nlist*)symtab)->n_value = (uint32_t)symbols->addr;
177symtab+= sizeof(struct nlist);
178
179strcpy(orig + dylib.symtab.stroff - sizeof(dylib) + symbols->pos, symbols->name);
180
181symbols = symbols->next;
182}
183
184fwrite(orig,
185dylib.symtab.stroff+// Sizeof symbol nlists
186dylib.symtab.strsize - sizeof(dylib) + 1// sizeof symbol strings
187, 1, outfile);
188
189
190fclose(outfile);
191
192exit(0);
193}
194
195int num_symbols(symbolList_t *list)
196{
197int retVal = 0;
198while(list)
199{
200retVal++;
201list = list->next;
202}
203return retVal;
204}
205
206int string_size(symbolList_t *list)
207{
208int retVal = 0;
209while(list)
210{
211retVal += strlen(list->name)+1;
212list = list->next;
213}
214return retVal;
215
216}
217
218void add_symbol(symbolList_t **list, char *name, uint32_t addr)
219{
220symbolList_t* entry = malloc(sizeof(symbolList_t));
221entry->next = (*list);
222
223if(*list) entry->pos = (*list)->pos + strlen((*list)->name) + 1;
224else entry->pos = 1;
225*list = entry;
226
227entry->addr = addr;
228entry->name = malloc(strlen(name)+1);
229strcpy(entry->name, name);
230}
231

Archive Download this file

Revision: HEAD