00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "elfstruc.h"
00022 #include "log.h"
00023 #include "htmacho.h"
00024 #include "htmachohd.h"
00025 #include "htmachoimg.h"
00026 #include "htendian.h"
00027 #include "stream.h"
00028 #include "tools.h"
00029
00030 #include "machostruc.h"
00031
00032 #include <stdlib.h>
00033
00034 static format_viewer_if *htmacho_ifs[] = {
00035 &htmachoheader_if,
00036 &htmachoimage_if,
00037 0
00038 };
00039
00040 static ht_view *htmacho_init(bounds *b, ht_streamfile *file, ht_format_group *format_group)
00041 {
00042 byte magic[4];
00043 file->seek(0);
00044 file->read(&magic, sizeof magic);
00045 if (memcmp(magic, "\xfe\xed\xfa\xce", 4) == 0) {
00046 ht_macho *g = new ht_macho();
00047 g->init(b, file, htmacho_ifs, format_group, 0, big_endian);
00048 return g;
00049 } else if (memcmp(magic, "\xce\xfa\xed\xfe", 4) == 0) {
00050 ht_macho *g = new ht_macho();
00051 g->init(b, file, htmacho_ifs, format_group, 0, little_endian);
00052 return g;
00053 }
00054 return NULL;
00055 }
00056
00057 format_viewer_if htmacho_if = {
00058 htmacho_init,
00059 0
00060 };
00061
00062
00063
00064
00065 void ht_macho::init(bounds *b, ht_streamfile *f, format_viewer_if **ifs, ht_format_group *format_group, FILEOFS header_ofs, endianess image_endianess)
00066 {
00067 ht_format_group::init(b, VO_SELECTABLE | VO_BROWSABLE | VO_RESIZE, DESC_MACHO, f, false, true, 0, format_group);
00068 VIEW_DEBUG_NAME("ht_macho");
00069
00070 LOG("%s: Mach-O: found header at %08x", file->get_filename(), header_ofs);
00071
00072 ht_macho_shared_data *macho_shared=(ht_macho_shared_data *)malloc(sizeof(ht_macho_shared_data));
00073
00074 shared_data = macho_shared;
00075 macho_shared->image_endianess = image_endianess;
00076 macho_shared->header_ofs = header_ofs;
00077 macho_shared->cmds.count = 0;
00078 macho_shared->cmds.cmds = NULL;
00079
00080
00081
00082
00083
00084
00085
00086 FILEOFS ofs;
00087
00088 file->seek(header_ofs);
00089 file->read(&macho_shared->header, sizeof macho_shared->header);
00090 create_host_struct(&macho_shared->header, MACHO_HEADER_struct, image_endianess);
00091
00092
00093 UINT nsections = 0;
00094 ofs = header_ofs+sizeof macho_shared->header;
00095 macho_shared->cmds.count = macho_shared->header.ncmds;
00096 macho_shared->cmds.cmds = (MACHO_COMMAND_U**)malloc(sizeof (MACHO_COMMAND_U*) * macho_shared->header.ncmds);
00097 for (UINT i=0; i<macho_shared->cmds.count; i++) {
00098 MACHO_COMMAND cmd;
00099 file->seek(ofs);
00100 file->read(&cmd, sizeof cmd);
00101 create_host_struct(&cmd, MACHO_COMMAND_struct, image_endianess);
00102 if (cmd.cmdsize>1024) break;
00103 macho_shared->cmds.cmds[i] = (MACHO_COMMAND_U*)malloc(cmd.cmdsize);
00104 file->seek(ofs);
00105 if (file->read(macho_shared->cmds.cmds[i], cmd.cmdsize) != cmd.cmdsize) {
00106 free(macho_shared->cmds.cmds[i]);
00107 break;
00108 }
00109 switch (cmd.cmd) {
00110 case LC_SEGMENT:
00111 create_host_struct(macho_shared->cmds.cmds[i], MACHO_SEGMENT_COMMAND_struct, image_endianess);
00112
00113 nsections += macho_shared->cmds.cmds[i]->segment.nsects;
00114 break;
00115 case LC_SYMTAB:
00116 create_host_struct(macho_shared->cmds.cmds[i], MACHO_SYMTAB_COMMAND_struct, image_endianess);
00117 break;
00118 case LC_THREAD:
00119 case LC_UNIXTHREAD: {
00120 MACHO_THREAD_COMMAND *c = (MACHO_THREAD_COMMAND*)macho_shared->cmds.cmds[i];
00121 create_host_struct(macho_shared->cmds.cmds[i], MACHO_THREAD_COMMAND_struct, image_endianess);
00122 switch (macho_shared->header.cputype) {
00123 case MACHO_CPU_TYPE_I386:
00124 switch (c->flavor) {
00125 case -1:
00126 create_host_struct(&c->state, MACHO_I386_THREAD_STATE_struct, image_endianess);
00127 break;
00128 }
00129 break;
00130 case MACHO_CPU_TYPE_POWERPC:
00131 switch (c->flavor) {
00132 case FLAVOR_PPC_THREAD_STATE:
00133 create_host_struct(&c->state, MACHO_PPC_THREAD_STATE_struct, image_endianess);
00134 break;
00135 }
00136 break;
00137 }
00138 }
00139 default:
00140 create_host_struct(macho_shared->cmds.cmds[i], MACHO_COMMAND_struct, image_endianess);
00141 }
00142 ofs += cmd.cmdsize;
00143 }
00144
00145
00146 ofs = header_ofs+sizeof macho_shared->header;
00147 macho_shared->sections.count = nsections;
00148 macho_shared->sections.sections = (MACHO_SECTION*)malloc(sizeof (MACHO_SECTION) * macho_shared->sections.count);
00149 UINT sec = 0;
00150 for (UINT i=0; i<macho_shared->cmds.count; i++) {
00151 if (macho_shared->cmds.cmds[i]->cmd.cmd == LC_SEGMENT) {
00152 FILEOFS sofs = ofs+sizeof (MACHO_SEGMENT_COMMAND);
00153 file->seek(sofs);
00154 for (UINT j=0; j<macho_shared->cmds.cmds[i]->segment.nsects; j++) {
00155 file->read(&macho_shared->sections.sections[sec], sizeof (MACHO_SECTION));
00156 create_host_struct(&macho_shared->sections.sections[sec], MACHO_SECTION_struct, image_endianess);
00157 sec++;
00158 }
00159 }
00160 ofs += macho_shared->cmds.cmds[i]->cmd.cmdsize;
00161 }
00162
00163
00164 ht_format_group::init_ifs(ifs);
00165 }
00166
00167 void ht_macho::done()
00168 {
00169 ht_format_group::done();
00170 }
00171
00172
00173
00174
00175
00176 bool macho_phys_and_mem_section(MACHO_SECTION *s, UINT machoclass)
00177 {
00178 return true;
00179 }
00180
00181 bool macho_valid_section(MACHO_SECTION *s, UINT machoclass)
00182 {
00183 return true;
00184 }
00185
00186 bool macho_addr_to_ofs(macho_sections *sections, UINT machoclass, MACHOAddress addr, dword *ofs)
00187 {
00188 MACHO_SECTION *s = sections->sections;
00189 for (UINT i=0; i < sections->count; i++) {
00190 if (macho_phys_and_mem_section(s, machoclass) &&
00191 (addr >= s->vmaddr) && (addr < s->vmaddr+s->vmsize)) {
00192 *ofs = addr - s->vmaddr + s->fileoff;
00193 return true;
00194 }
00195 s++;
00196 }
00197 return false;
00198 }
00199
00200 bool macho_addr_to_section(macho_sections *sections, UINT machoclass, MACHOAddress addr, int *section)
00201 {
00202 MACHO_SECTION *s = sections->sections;
00203 for (UINT i=0; i < sections->count; i++) {
00204 if ((macho_valid_section(s, machoclass)) && (addr >= s->vmaddr) && (addr < s->vmaddr + s->vmsize)) {
00205 *section = i;
00206 return true;
00207 }
00208 s++;
00209 }
00210 return false;
00211 }
00212
00213 bool macho_addr_is_valid(macho_sections *sections, UINT machoclass, MACHOAddress addr)
00214 {
00215 MACHO_SECTION *s = sections->sections;
00216 for (UINT i=0; i < sections->count; i++) {
00217 if ((macho_valid_section(s, machoclass)) && (addr >= s->vmaddr) && (addr < s->vmaddr + s->vmsize)) {
00218 return true;
00219 }
00220 s++;
00221 }
00222 return false;
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 bool macho_ofs_to_addr(macho_sections *sections, UINT machoclass, dword ofs, MACHOAddress *addr)
00235 {
00236 MACHO_SECTION *s = sections->sections;
00237 for (UINT i=0; i < sections->count; i++) {
00238 if ((macho_phys_and_mem_section(s, machoclass)) && (ofs>=s->fileoff) && (ofs<s->fileoff+s->vmsize)) {
00239 *addr = ofs - s->fileoff + s->vmaddr;
00240 return true;
00241 }
00242 s++;
00243 }
00244 return false;
00245 }
00246
00247 bool macho_ofs_to_section(macho_sections *sections, UINT machoclass, dword ofs, dword *section)
00248 {
00249 MACHO_SECTION *s = sections->sections;
00250 for (UINT i=0; i < sections->count; i++) {
00251 if ((macho_valid_section(s, machoclass)) && (ofs >= s->fileoff) && (ofs<s->fileoff+s->vmsize)) {
00252 *section = i;
00253 return true;
00254 }
00255 s++;
00256 }
00257 return false;
00258 }
00259
00260
00261
00262
00263