00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "log.h"
00022 #include "htmachoimg.h"
00023 #include "htpal.h"
00024 #include "htstring.h"
00025 #include "formats.h"
00026 #include "snprintf.h"
00027 #include "tools.h"
00028
00029 #include "machostruc.h"
00030 #include "macho_analy.h"
00031
00032 static ht_view *htmachoimage_init(bounds *b, ht_streamfile *file, ht_format_group *group)
00033 {
00034 ht_macho_shared_data *macho_shared=(ht_macho_shared_data *)group->get_shared_data();
00035
00036
00037
00038 LOG("%s: Mach-O: loading image (starting analyser)...", file->get_filename());
00039 MachoAnalyser *p = new MachoAnalyser();
00040 p->init(macho_shared, file);
00041
00042 bounds c=*b;
00043 ht_group *g=new ht_group();
00044 g->init(&c, VO_RESIZE, DESC_MACHO_IMAGE"-g");
00045 AnalyInfoline *head;
00046
00047 c.y+=2;
00048 c.h-=2;
00049 ht_macho_aviewer *v=new ht_macho_aviewer();
00050 v->init(&c, DESC_MACHO_IMAGE, VC_EDIT | VC_GOTO | VC_SEARCH, file, group, p, macho_shared);
00051
00052 c.y-=2;
00053 c.h=2;
00054 head=new AnalyInfoline();
00055 head->init(&c, v, ANALY_STATUS_DEFAULT);
00056
00057 v->attachInfoline(head);
00058
00059
00060 Address *low = NULL;
00061 Address *high = NULL;
00062
00063 MACHOAddress l, h;
00064 l = (dword)-1;
00065 h = 0;
00066 MACHO_SECTION *s = macho_shared->sections.sections;
00067 for (UINT i=0; i < macho_shared->sections.count; i++) {
00068 if (macho_valid_section(s, 0)) {
00069 if (s->vmaddr < l) l = s->vmaddr;
00070 if ((s->vmaddr + s->vmsize > h) && s->vmsize) h=s->vmaddr + s->vmsize - 1;
00071 }
00072 s++;
00073 }
00074 low = p->createAddress32(l);
00075 high = p->createAddress32(h);
00076
00077 ht_analy_sub *analy=new ht_analy_sub();
00078
00079 if (low->compareTo(high) < 0) {
00080 analy->init(file, v, p, low, high);
00081 v->analy_sub = analy;
00082 v->insertsub(analy);
00083 } else {
00084 delete analy;
00085 v->done();
00086 delete v;
00087 head->done();
00088 delete head;
00089 g->done();
00090 delete g;
00091 delete high;
00092 delete low;
00093 return NULL;
00094 }
00095
00096 delete high;
00097 delete low;
00098
00099 v->sendmsg(msg_complete_init, 0);
00100
00101 Address *tmpaddr = NULL;
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 MACHO_COMMAND_U **pp = macho_shared->cmds.cmds;
00117 for (UINT i=0; i < macho_shared->cmds.count; i++) {
00118 if (((*pp)->cmd.cmd == LC_UNIXTHREAD) || ((*pp)->cmd.cmd == LC_THREAD)) {
00119 MACHO_THREAD_COMMAND *s = (MACHO_THREAD_COMMAND*)*pp;
00120 Address *entry;
00121 switch (macho_shared->header.cputype) {
00122 case MACHO_CPU_TYPE_POWERPC:
00123 entry = p->createAddress32(s->state.state_ppc.srr0);
00124 break;
00125 case MACHO_CPU_TYPE_I386:
00126 entry = p->createAddress32(s->state.state_i386.eip);
00127 break;
00128 default: assert(0);
00129 }
00130 v->gotoAddress(entry, NULL);
00131 delete entry;
00132 break;
00133 }
00134 pp++;
00135 }
00136
00137 g->insert(head);
00138 g->insert(v);
00139
00140 g->setpalette(palkey_generic_window_default);
00141
00142
00143 return g;
00144 }
00145
00146 format_viewer_if htmachoimage_if = {
00147 htmachoimage_init,
00148 0
00149 };
00150
00151
00152
00153
00154 void ht_macho_aviewer::init(bounds *b, char *desc, int caps, ht_streamfile *File, ht_format_group *format_group, Analyser *Analy, ht_macho_shared_data *MACHO_shared)
00155 {
00156 ht_aviewer::init(b, desc, caps, File, format_group, Analy);
00157 macho_shared = MACHO_shared;
00158 }
00159
00160 void ht_macho_aviewer::setAnalyser(Analyser *a)
00161 {
00162 ((MachoAnalyser *)a)->macho_shared = macho_shared;
00163 ((MachoAnalyser *)a)->file = file;
00164 analy = a;
00165 analy_sub->setAnalyser(a);
00166 }