Chameleon

Chameleon Svn Source Tree

Root/branches/meklort/i386/util/dyldsymboltool.c

Source at commit 735 created 13 years 2 months ago.
By meklort, GUI module bugfixes. Kext Patcher additions.
1/*
2 * Copyright (c) 2010 Evan Lojewski. All rights reserved.
3 *
4 *dyldsymboltool
5 *
6 *Generates a dylib ile 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 bootFile loadAddr outfile\n");
51
52exit(-1);
53}
54
55
56char line[256];
57char* command = malloc(strlen(argv[1]) + sizeof("nm -g "));
58FILE *fpipe;
59
60symbols_dylib_t dylib;
61symbolList_t*symbols = NULL;
62
63uint32_t start_addr = 0;
64
65
66
67
68
69
70// Parse boot.sys (arg1) to get symtab
71sprintf(command, "nm -g %s", argv[1]);// TODO: read boot.sym directly, no need for nm
72
73if ( !(fpipe = (FILE*)popen(command,"r")) )
74{ // If fpipe is NULL
75perror("Problems with pipe");
76exit(1);
77}
78
79while ( fgets( line, sizeof line, fpipe))
80{
81uint32_t address = 0;
82char* addr = strtok(line, " ");
83strtok(NULL, " ");
84char* name = strtok(NULL, " ");
85name[strlen(name)-1] = 0;// remove newline
86sscanf(addr, "%x", &address);
87if(strcmp(name, VOID_SYMBOL) == 0) start_addr = address;
88add_symbol(&symbols, name, address);
89}
90
91
92pclose(fpipe);
93
94if(start_addr == 0)
95{
96fprintf(stderr, "Unable to locate Symbol.dylib start function\n");
97exit(1);
98}
99
100add_symbol(&symbols, START_SYMBOL, start_addr);
101
102
103/* Header command info */
104dylib.header.ncmds = 2;
105dylib.header.sizeofcmds = sizeof(dylib) - sizeof(struct mach_header);// + dylib.symtab.nsyms * sizeof(struct nlist) + dylib.symtab.strsize;
106
107dylib.header.magic = MH_MAGIC;
108dylib.header.cputype = CPU_TYPE_X86;
109dylib.header.cpusubtype = /*CPUSUBTYPE_I386*/ 3;
110dylib.header.filetype = MH_DYLIB;
111dylib.header.flags = MH_NOUNDEFS | MH_DYLDLINK | MH_NO_REEXPORTED_DYLIBS;
112
113/* Load Commands - dylib id */
114dylib.dylib_info.cmd = LC_ID_DYLIB;
115dylib.dylib_info.cmdsize = sizeof(struct dylib_command) + sizeof(dylib.module_name);// todo: verify
116dylib.dylib_info.dylib.name.offset = sizeof(struct dylib_command);
117dylib.dylib_info.dylib.timestamp = 0;// TODO: populate with time
118dylib.dylib_info.dylib.current_version = 0;// TODO
119dylib.dylib_info.dylib.compatibility_version = 0;// TODO
120
121
122//int offset = dylib.dylib_info.cmdsize%4 ? 4 - (dylib.dylib_info.cmdsize % 4) : 0;
123//dylib.dylib_info.cmdsize += offset;
124//dylib.header.sizeofcmds += offset;
125
126sprintf(dylib.module_name, "%s", DYLIB_NAME);
127
128/* Load Commands - Symtable */
129dylib.symtab.cmd = LC_SYMTAB;
130dylib.symtab.symoff = sizeof(dylib);
131dylib.symtab.nsyms = num_symbols(symbols);
132dylib.symtab.stroff = sizeof(dylib) + dylib.symtab.nsyms * sizeof(struct nlist);
133dylib.symtab.strsize = string_size(symbols);
134dylib.symtab.cmdsize = sizeof(struct symtab_command);
135
136
137
138FILE* outfile = fopen(argv[2], "w");
139fwrite(&dylib,sizeof(dylib)/* Sizeof header + module name */
140, 1, outfile);
141
142char* symtab = malloc(dylib.symtab.stroff + dylib.symtab.strsize - sizeof(dylib) + 1); // Add extra 1 for last symbol
143bzero(symtab, dylib.symtab.nsyms * sizeof(struct nlist) + dylib.symtab.strsize + 1);
144char* orig = symtab;
145
146//symtab += offset;
147
148
149while(symbols)
150{
151
152((struct nlist*)symtab)->n_un.n_strx = symbols->pos;
153((struct nlist*)symtab)->n_type = 0xF;// TODO: read from boot.sys
154((struct nlist*)symtab)->n_sect = 0;
155((struct nlist*)symtab)->n_desc = REFERENCE_FLAG_DEFINED;
156((struct nlist*)symtab)->n_value = (uint32_t)symbols->addr;
157symtab+= sizeof(struct nlist);
158
159strcpy(orig + dylib.symtab.stroff - sizeof(dylib) + symbols->pos, symbols->name);
160
161symbols = symbols->next;
162}
163
164fwrite(orig,
165dylib.symtab.stroff+// Sizeof symbol nlists
166dylib.symtab.strsize - sizeof(dylib) + 1// sizeof symbol strings
167, 1, outfile);
168
169
170fclose(outfile);
171
172exit(0);
173}
174
175int num_symbols(symbolList_t* list)
176{
177int retVal = 0;
178while(list)
179{
180retVal++;
181list = list->next;
182}
183return retVal;
184}
185
186int string_size(symbolList_t* list)
187{
188int retVal = 0;
189while(list)
190{
191retVal += strlen(list->name)+1;
192list = list->next;
193}
194return retVal;
195
196}
197
198void add_symbol(symbolList_t** list, char* name, uint32_t addr)
199{
200symbolList_t* entry = malloc(sizeof(symbolList_t));
201entry->next = (*list);
202
203if(*list) entry->pos = (*list)->pos + strlen((*list)->name) + 1;
204else entry->pos = 1;
205*list = entry;
206
207entry->addr = addr;
208entry->name = malloc(strlen(name)+1);
209strcpy(entry->name, name);
210}
211

Archive Download this file

Revision: 735