00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "machostruc.h"
00022 #include "htatom.h"
00023 #include "htmacho.h"
00024 #include "htmachohd.h"
00025 #include "httag.h"
00026 #include "formats.h"
00027 #include "snprintf.h"
00028
00029 static ht_mask_ptable machoheader[]=
00030 {
00031 {"magic", STATICTAG_EDIT_DWORD_VE("00000000")},
00032 {"cputype", STATICTAG_EDIT_DWORD_VE("00000004")},
00033 {"cpusubtype", STATICTAG_EDIT_DWORD_VE("00000008")},
00034 {"filetype", STATICTAG_EDIT_DWORD_VE("0000000c")},
00035 {"number of cmds", STATICTAG_EDIT_DWORD_VE("00000010")},
00036 {"size of cmds", STATICTAG_EDIT_DWORD_VE("00000014")},
00037 {"flags", STATICTAG_EDIT_DWORD_VE("00000018")},
00038 {0, 0}
00039 };
00040
00041 static ht_mask_ptable macho_segment_header[]=
00042 {
00043 {"cmd", STATICTAG_EDIT_DWORD_VE("00000000")},
00044 {"cmdsize", STATICTAG_EDIT_DWORD_VE("00000004")},
00045 {"name",
00046 STATICTAG_EDIT_CHAR("00000008")STATICTAG_EDIT_CHAR("00000009")
00047 STATICTAG_EDIT_CHAR("0000000a")STATICTAG_EDIT_CHAR("0000000b")
00048 STATICTAG_EDIT_CHAR("0000000c")STATICTAG_EDIT_CHAR("0000000d")
00049 STATICTAG_EDIT_CHAR("0000000e")STATICTAG_EDIT_CHAR("0000000f")
00050 STATICTAG_EDIT_CHAR("00000010")STATICTAG_EDIT_CHAR("00000011")
00051 STATICTAG_EDIT_CHAR("00000012")STATICTAG_EDIT_CHAR("00000013")
00052 STATICTAG_EDIT_CHAR("00000014")STATICTAG_EDIT_CHAR("00000015")
00053 STATICTAG_EDIT_CHAR("00000016")STATICTAG_EDIT_CHAR("00000017")
00054 },
00055 {"virtual address", STATICTAG_EDIT_DWORD_VE("00000018")},
00056 {"virtual size", STATICTAG_EDIT_DWORD_VE("0000001c")},
00057 {"file offset", STATICTAG_EDIT_DWORD_VE("00000020")},
00058 {"file size", STATICTAG_EDIT_DWORD_VE("00000024")},
00059 {"max VM protection", STATICTAG_EDIT_DWORD_VE("00000028")},
00060 {"init VM protection", STATICTAG_EDIT_DWORD_VE("0000002c")},
00061 {"number of sections", STATICTAG_EDIT_DWORD_VE("00000030")},
00062 {"flags", STATICTAG_EDIT_DWORD_VE("00000034")},
00063 {0, 0}
00064 };
00065
00066 static ht_mask_ptable macho_section_header[]=
00067 {
00068 {"section name",
00069 STATICTAG_EDIT_CHAR("00000000")STATICTAG_EDIT_CHAR("00000001")
00070 STATICTAG_EDIT_CHAR("00000002")STATICTAG_EDIT_CHAR("00000003")
00071 STATICTAG_EDIT_CHAR("00000004")STATICTAG_EDIT_CHAR("00000005")
00072 STATICTAG_EDIT_CHAR("00000006")STATICTAG_EDIT_CHAR("00000007")
00073 STATICTAG_EDIT_CHAR("00000008")STATICTAG_EDIT_CHAR("00000009")
00074 STATICTAG_EDIT_CHAR("0000000a")STATICTAG_EDIT_CHAR("0000000b")
00075 STATICTAG_EDIT_CHAR("0000000c")STATICTAG_EDIT_CHAR("0000000d")
00076 STATICTAG_EDIT_CHAR("0000000e")STATICTAG_EDIT_CHAR("0000000f")
00077 },
00078 {"segment name",
00079 STATICTAG_EDIT_CHAR("00000010")STATICTAG_EDIT_CHAR("00000011")
00080 STATICTAG_EDIT_CHAR("00000012")STATICTAG_EDIT_CHAR("00000013")
00081 STATICTAG_EDIT_CHAR("00000014")STATICTAG_EDIT_CHAR("00000015")
00082 STATICTAG_EDIT_CHAR("00000016")STATICTAG_EDIT_CHAR("00000017")
00083 STATICTAG_EDIT_CHAR("00000018")STATICTAG_EDIT_CHAR("00000019")
00084 STATICTAG_EDIT_CHAR("0000001a")STATICTAG_EDIT_CHAR("0000001b")
00085 STATICTAG_EDIT_CHAR("0000001c")STATICTAG_EDIT_CHAR("0000001d")
00086 STATICTAG_EDIT_CHAR("0000001e")STATICTAG_EDIT_CHAR("0000001f")
00087 },
00088 {"virtual address", STATICTAG_EDIT_DWORD_VE("00000020")},
00089 {"virtual size", STATICTAG_EDIT_DWORD_VE("00000024")},
00090 {"file offset", STATICTAG_EDIT_DWORD_VE("00000028")},
00091 {"alignment", STATICTAG_EDIT_DWORD_VE("0000002c")},
00092 {"relocation file offset", STATICTAG_EDIT_DWORD_VE("00000030")},
00093 {"number of relocation entries",STATICTAG_EDIT_DWORD_VE("00000034")},
00094 {"flags", STATICTAG_EDIT_DWORD_VE("00000038")},
00095 {"reserved1", STATICTAG_EDIT_DWORD_VE("0000003c")},
00096 {"reserved2", STATICTAG_EDIT_DWORD_VE("00000040")},
00097 {0, 0}
00098 };
00099
00100 static ht_mask_ptable macho_thread_header[]=
00101 {
00102 {"cmd", STATICTAG_EDIT_DWORD_VE("00000000")},
00103 {"cmdsize", STATICTAG_EDIT_DWORD_VE("00000004")},
00104 {"flavor", STATICTAG_EDIT_DWORD_VE("00000008")},
00105 {"count (of 32bit words)", STATICTAG_EDIT_DWORD_VE("0000000c")},
00106 {0, 0}
00107 };
00108
00109 static ht_mask_ptable macho_ppc_thread_state[]=
00110 {
00111 {"srr0", STATICTAG_EDIT_DWORD_VE("00000000")},
00112 {"srr1", STATICTAG_EDIT_DWORD_VE("00000004")},
00113 {"flavor", STATICTAG_EDIT_DWORD_VE("00000008")},
00114 {"r0", STATICTAG_EDIT_DWORD_VE("0000000c")},
00115 {"r1", STATICTAG_EDIT_DWORD_VE("00000010")},
00116 {"r2", STATICTAG_EDIT_DWORD_VE("00000014")},
00117 {"r3", STATICTAG_EDIT_DWORD_VE("00000018")},
00118 {"r4", STATICTAG_EDIT_DWORD_VE("0000001c")},
00119 {"r5", STATICTAG_EDIT_DWORD_VE("00000020")},
00120 {"r6", STATICTAG_EDIT_DWORD_VE("00000024")},
00121 {"r7", STATICTAG_EDIT_DWORD_VE("00000028")},
00122 {"r8", STATICTAG_EDIT_DWORD_VE("0000002c")},
00123 {"r9", STATICTAG_EDIT_DWORD_VE("00000030")},
00124 {"r10", STATICTAG_EDIT_DWORD_VE("00000034")},
00125 {"r11", STATICTAG_EDIT_DWORD_VE("00000038")},
00126 {"r12", STATICTAG_EDIT_DWORD_VE("0000003c")},
00127 {"r13", STATICTAG_EDIT_DWORD_VE("00000040")},
00128 {"r14", STATICTAG_EDIT_DWORD_VE("00000044")},
00129 {"r15", STATICTAG_EDIT_DWORD_VE("00000048")},
00130 {"r16", STATICTAG_EDIT_DWORD_VE("0000004c")},
00131 {"r17", STATICTAG_EDIT_DWORD_VE("00000050")},
00132 {"r18", STATICTAG_EDIT_DWORD_VE("00000054")},
00133 {"r19", STATICTAG_EDIT_DWORD_VE("00000058")},
00134 {"r20", STATICTAG_EDIT_DWORD_VE("0000005c")},
00135 {"r21", STATICTAG_EDIT_DWORD_VE("00000060")},
00136 {"r22", STATICTAG_EDIT_DWORD_VE("00000064")},
00137 {"r23", STATICTAG_EDIT_DWORD_VE("00000068")},
00138 {"r24", STATICTAG_EDIT_DWORD_VE("0000006c")},
00139 {"r25", STATICTAG_EDIT_DWORD_VE("00000070")},
00140 {"r26", STATICTAG_EDIT_DWORD_VE("00000074")},
00141 {"r27", STATICTAG_EDIT_DWORD_VE("00000078")},
00142 {"r28", STATICTAG_EDIT_DWORD_VE("0000007c")},
00143 {"r29", STATICTAG_EDIT_DWORD_VE("00000080")},
00144 {"r30", STATICTAG_EDIT_DWORD_VE("00000084")},
00145 {"r31", STATICTAG_EDIT_DWORD_VE("00000088")},
00146 {"cr", STATICTAG_EDIT_DWORD_VE("0000008c")},
00147 {"xer", STATICTAG_EDIT_DWORD_VE("00000090")},
00148 {"lr", STATICTAG_EDIT_DWORD_VE("00000094")},
00149 {"ctr", STATICTAG_EDIT_DWORD_VE("00000098")},
00150 {"mq", STATICTAG_EDIT_DWORD_VE("0000009c")},
00151 {"vrsave", STATICTAG_EDIT_DWORD_VE("000000a0")},
00152 {0, 0}
00153 };
00154
00155 static ht_mask_ptable macho_i386_thread_state[]=
00156 {
00157 {"eax", STATICTAG_EDIT_DWORD_VE("00000000")},
00158 {"ebx", STATICTAG_EDIT_DWORD_VE("00000004")},
00159 {"ecx", STATICTAG_EDIT_DWORD_VE("00000008")},
00160 {"edx", STATICTAG_EDIT_DWORD_VE("0000000c")},
00161 {"edi", STATICTAG_EDIT_DWORD_VE("00000010")},
00162 {"esi", STATICTAG_EDIT_DWORD_VE("00000014")},
00163 {"ebp", STATICTAG_EDIT_DWORD_VE("00000018")},
00164 {"esp", STATICTAG_EDIT_DWORD_VE("0000001c")},
00165 {"ss", STATICTAG_EDIT_DWORD_VE("00000020")},
00166 {"eflags", STATICTAG_EDIT_DWORD_VE("00000024")},
00167 {"eip", STATICTAG_EDIT_DWORD_VE("00000028")},
00168 {"cs", STATICTAG_EDIT_DWORD_VE("0000002c")},
00169 {"ds", STATICTAG_EDIT_DWORD_VE("00000030")},
00170 {"es", STATICTAG_EDIT_DWORD_VE("00000034")},
00171 {"fs", STATICTAG_EDIT_DWORD_VE("00000038")},
00172 {"gs", STATICTAG_EDIT_DWORD_VE("0000003c")},
00173 {0, 0}
00174 };
00175
00176 static ht_view *htmachoheader_init(bounds *b, ht_streamfile *file, ht_format_group *group)
00177 {
00178 ht_macho_shared_data *macho_shared=(ht_macho_shared_data *)group->get_shared_data();
00179
00180 ht_uformat_viewer *v=new ht_uformat_viewer();
00181 v->init(b, DESC_MACHO_HEADER, VC_EDIT, file, group);
00182 ht_mask_sub *m = new ht_mask_sub();
00183 m->init(file, 0);
00184 char info[128];
00185 ht_snprintf(info, sizeof info, "* Mach-O header at offset %08x", macho_shared->header_ofs);
00186 bool isbigendian;
00187 switch (macho_shared->image_endianess) {
00188 case little_endian: isbigendian = false; break;
00189 case big_endian: isbigendian = true; break;
00190 }
00191 m->add_mask(info);
00192 m->add_staticmask_ptable(machoheader, macho_shared->header_ofs, isbigendian);
00193
00194 FILEOFS ofs = macho_shared->header_ofs+7*4;
00195 for (UINT i=0; i<macho_shared->cmds.count; i++) {
00196 switch (macho_shared->cmds.cmds[i]->cmd.cmd) {
00197 case LC_SEGMENT: {
00198 MACHO_SEGMENT_COMMAND *c = (MACHO_SEGMENT_COMMAND *)macho_shared->cmds.cmds[i];
00199 char segname[17];
00200 ht_snprintf(segname, sizeof segname, "%s", c->segname);
00201 char info[128];
00202 ht_snprintf(info, sizeof info, "** segment %s: vaddr %08x vsize %08x fileofs %08x, filesize %08x", segname, c->vmaddr, c->vmsize, c->fileoff, c->filesize);
00203 m->add_mask(info);
00204 m->add_staticmask_ptable(macho_segment_header, ofs, isbigendian);
00205 FILEOFS sofs = sizeof (MACHO_SEGMENT_COMMAND);
00206 for (UINT j=0; j<c->nsects; j++) {
00207 ht_snprintf(info, sizeof info, "**** section %d ****", j);
00208 m->add_mask(info);
00209 m->add_staticmask_ptable(macho_section_header, ofs+sofs, isbigendian);
00210 sofs += 9*4+16+16;
00211 }
00212 break;
00213 }
00214 case LC_SYMTAB: {
00215 char info[128];
00216 ht_snprintf(info, sizeof info, "** SYMTAB cmdsize %08x", macho_shared->cmds.cmds[i]->cmd.cmdsize);
00217 m->add_mask(info);
00218 break;
00219 }
00220 case LC_SYMSEG: {
00221 char info[128];
00222 ht_snprintf(info, sizeof info, "** SYMSEG cmdsize %08x", macho_shared->cmds.cmds[i]->cmd.cmdsize);
00223 m->add_mask(info);
00224 break;
00225 }
00226 case LC_UNIXTHREAD:
00227 case LC_THREAD: {
00228 MACHO_THREAD_COMMAND *c = &macho_shared->cmds.cmds[i]->thread;
00229 char info[128];
00230 ht_snprintf(info, sizeof info, "** %s", (macho_shared->cmds.cmds[i]->cmd.cmd == LC_UNIXTHREAD) ? "UNIXTHREAD" : "THREAD");
00231 m->add_mask(info);
00232 m->add_staticmask_ptable(macho_thread_header, ofs, isbigendian);
00233 switch (macho_shared->header.cputype) {
00234 case MACHO_CPU_TYPE_I386:
00235 switch (c->flavor) {
00236 case -1:
00237 m->add_staticmask_ptable(macho_i386_thread_state, ofs+4*4, isbigendian);
00238 break;
00239 }
00240 break;
00241 case MACHO_CPU_TYPE_POWERPC:
00242 switch (c->flavor) {
00243 case FLAVOR_PPC_THREAD_STATE:
00244 m->add_staticmask_ptable(macho_ppc_thread_state, ofs+4*4, isbigendian);
00245 break;
00246 }
00247 break;
00248 }
00249 break;
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 case LC_LOADFVMLIB: {
00264 char info[128];
00265 ht_snprintf(info, sizeof info, "** LOADFVMLIB cmdsize %08x", macho_shared->cmds.cmds[i]->cmd.cmdsize);
00266 m->add_mask(info);
00267 break;
00268 }
00269 case LC_IDFVMLIB: {
00270 char info[128];
00271 ht_snprintf(info, sizeof info, "** IDFVMLIB cmdsize %08x", macho_shared->cmds.cmds[i]->cmd.cmdsize);
00272 m->add_mask(info);
00273 break;
00274 }
00275 case LC_IDENT: {
00276 char info[128];
00277 ht_snprintf(info, sizeof info, "** IDENT (obsolete) cmdsize %08x", macho_shared->cmds.cmds[i]->cmd.cmdsize);
00278 m->add_mask(info);
00279 break;
00280 }
00281 case LC_FVMFILE: {
00282 char info[128];
00283 ht_snprintf(info, sizeof info, "** FVMFILE cmdsize %08x", macho_shared->cmds.cmds[i]->cmd.cmdsize);
00284 m->add_mask(info);
00285 break;
00286 }
00287 case LC_PREPAGE: {
00288 char info[128];
00289 ht_snprintf(info, sizeof info, "** PREPAGE cmdsize %08x", macho_shared->cmds.cmds[i]->cmd.cmdsize);
00290 m->add_mask(info);
00291 break;
00292 }
00293 case LC_DYSYMTAB: {
00294 char info[128];
00295 ht_snprintf(info, sizeof info, "** DYSYMTAB cmdsize %08x", macho_shared->cmds.cmds[i]->cmd.cmdsize);
00296 m->add_mask(info);
00297 break;
00298 }
00299 case LC_LOAD_DYLIB: {
00300 char info[128];
00301 ht_snprintf(info, sizeof info, "** LOAD_DYLIB cmdsize %08x", macho_shared->cmds.cmds[i]->cmd.cmdsize);
00302 m->add_mask(info);
00303 break;
00304 }
00305 case LC_ID_DYLIB: {
00306 char info[128];
00307 ht_snprintf(info, sizeof info, "** ID_DYLIB cmdsize %08x", macho_shared->cmds.cmds[i]->cmd.cmdsize);
00308 m->add_mask(info);
00309 break;
00310 }
00311 case LC_LOAD_DYLINKER: {
00312 char info[128];
00313 ht_snprintf(info, sizeof info, "** LOAD_DYLINKER cmdsize %08x", macho_shared->cmds.cmds[i]->cmd.cmdsize);
00314 m->add_mask(info);
00315 break;
00316 }
00317 case LC_ID_DYLINKER: {
00318 char info[128];
00319 ht_snprintf(info, sizeof info, "** ID_DYLINKER cmdsize %08x", macho_shared->cmds.cmds[i]->cmd.cmdsize);
00320 m->add_mask(info);
00321 break;
00322 }
00323 case LC_PREBOUND_DYLIB: {
00324 char info[128];
00325 ht_snprintf(info, sizeof info, "** PREBOUND_DYLIB cmdsize %08x", macho_shared->cmds.cmds[i]->cmd.cmdsize);
00326 m->add_mask(info);
00327 break;
00328 }
00329 default: {
00330 char info[128];
00331 ht_snprintf(info, sizeof info, "** unsupported load command %08x, size %08x", macho_shared->cmds.cmds[i]->cmd.cmd, macho_shared->cmds.cmds[i]->cmd.cmdsize);
00332 m->add_mask(info);
00333 }
00334 }
00335 ofs += macho_shared->cmds.cmds[i]->cmd.cmdsize;
00336 }
00337 v->insertsub(m);
00338 return v;
00339 }
00340
00341 format_viewer_if htmachoheader_if = {
00342 htmachoheader_init,
00343 0
00344 };