00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <string.h>
00022
00023 #include "cmds.h"
00024 #include "htctrl.h"
00025 #include "htiobox.h"
00026 #include "hthex.h"
00027 #include "htmenu.h"
00028 #include "htsearch.h"
00029 #include "snprintf.h"
00030 #include "stream.h"
00031 #include "tools.h"
00032
00033 extern "C" {
00034 #include "evalx.h"
00035 #include "regex.h"
00036 }
00037
00038 ht_view *hthex_init(bounds *b, ht_streamfile *file, ht_format_group *group)
00039 {
00040 ht_hex_viewer *v=new ht_hex_viewer();
00041 v->init(b, DESC_HEX, VC_EDIT | VC_GOTO | VC_SEARCH | VC_REPLACE | VC_RESIZE, file, group);
00042
00043 v->search_caps|=SEARCHMODE_BIN | SEARCHMODE_EVALSTR | SEARCHMODE_EXPR;
00044
00045 v->h=new ht_hex_file_sub();
00046 v->h->init(file, 0x0, file->get_size(), 16, 0);
00047
00048 v->insertsub(v->h);
00049 return v;
00050 }
00051
00052 format_viewer_if hthex_if = {
00053 hthex_init,
00054 0
00055 };
00056
00057
00058
00059
00060
00061 void ht_hex_viewer::get_pindicator_str(char *buf)
00062 {
00063 FILEOFS o;
00064 FILEOFS sel_start, sel_end;
00065 pselect_get(&sel_start, &sel_end);
00066 if (get_current_offset(&o)) {
00067 char ttemp[1024];
00068 if (sel_end-sel_start > 0) {
00069 ht_snprintf(ttemp, sizeof ttemp, "selection %xh-%xh (%d byte%s)", sel_start, sel_end-1, sel_end-sel_start, sel_end-sel_start==1?"":"s");
00070 } else {
00071 ttemp[0]=0;
00072 }
00073
00074 ht_snprintf(buf, 1024, " %s %xh/%u %s", edit() ? "edit" : "view", o, o, ttemp);
00075 } else {
00076 strcpy(buf, "?");
00077 }
00078 }
00079
00080 bool ht_hex_viewer::get_vscrollbar_pos(int *pstart, int *psize)
00081 {
00082 int s=file->get_size();
00083 if (s) {
00084 int ll = h->get_line_length();
00085 int z=MIN(size.h*ll, s-(int)top.line_id.id1);
00086 return scrollbar_pos(top.line_id.id1, z, s, pstart, psize);
00087 }
00088 return false;
00089 }
00090
00091 void ht_hex_viewer::handlemsg(htmsg *msg)
00092 {
00093 switch (msg->msg) {
00094 case msg_filesize_changed:
00095 htmsg m;
00096 m.msg=msg_filesize_changed;
00097 m.type=mt_broadcast;
00098 sendsubmsg(&m);
00099
00100 uf_initialized=false;
00101 complete_init();
00102
00103 dirtyview();
00104 return;
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 case cmd_hex_entropy: {
00133 FILEOFS ofs;
00134 if (get_current_offset(&ofs)) {
00135 byte buf[64];
00136 if (pread(ofs, buf, 64)==64) {
00137 int e = calc_entropy2(buf, 64);
00138 infobox("64-byte entropy at offset %08x: %d %%", ofs, e);
00139 }
00140 }
00141 clearmsg(msg);
00142 return;
00143 }
00144 case cmd_hex_display_bytes: {
00145 char result[256];
00146 sprintf(result, "%d", h->get_line_length());
00147 if (inputbox("Change display width", "~Line length (Bytes)", result, 256)) {
00148 char *p;
00149 int ll = strtoul(result, &p, 10);
00150 if (ll>0 && ll<=32) {
00151 h->set_line_length(ll);
00152 } else {
00153 errorbox("Line length must be > 0 and <= 32!");
00154 }
00155 }
00156 clearmsg(msg);
00157 return;
00158 }
00159 case msg_contextmenuquery: {
00160 ht_static_context_menu *m=new ht_static_context_menu();
00161 m->init("~Local-Hex");
00162 m->insert_entry("~Block operations", "Ctrl+B", cmd_file_blockop, K_Control_B, 1);
00163 m->insert_entry("~Replace", "Ctrl+E", cmd_file_replace, K_Control_E, 1);
00164 m->insert_entry("~Entropy", "Ctrl+T", cmd_hex_entropy, K_Control_T, 1);
00165 m->insert_entry("~Change display width...", "Ctrl+O", cmd_hex_display_bytes, K_Control_O, 1);
00166
00167 msg->msg = msg_retval;
00168 msg->data1.ptr = m;
00169 return;
00170 }
00171 }
00172 ht_uformat_viewer::handlemsg(msg);
00173 }
00174
00175 bool ht_hex_viewer::pos_to_offset(viewer_pos p, FILEOFS *ofs)
00176 {
00177 *ofs = p.u.line_id.id1 + p.u.tag_idx;
00178 return true;
00179 }
00180
00181 bool ht_hex_viewer::offset_to_pos(FILEOFS ofs, viewer_pos *p)
00182 {
00183 int ll = h->get_line_length();
00184 clear_viewer_pos(p);
00185 p->u.sub = first_sub;
00186 p->u.line_id.id1 = ofs - (ofs % ll);
00187 p->u.line_id.id2 = 0;
00188 p->u.tag_idx = ofs % ll;
00189 return true;
00190 }
00191
00192 bool ht_hex_viewer::qword_to_pos(qword q, viewer_pos *p)
00193 {
00194 int ll = h->get_line_length();
00195 ht_linear_sub *s = (ht_linear_sub*)cursor.sub;
00196 FILEOFS ofs = QWORD_GET_INT(q);
00197 clear_viewer_pos(p);
00198 p->u.sub = s;
00199 p->u.tag_idx = ofs % ll;
00200 return s->convert_ofs_to_id(ofs, &p->u.line_id);
00201 }
00202
00203 int ht_hex_viewer::symbol_handler(eval_scalar *result, char *name)
00204 {
00205 if (strcmp(name, "$") == 0) {
00206 FILEOFS ofs;
00207 if (!pos_to_offset(*(viewer_pos*)&cursor, &ofs)) return 0;
00208 scalar_create_int_c(result, ofs);
00209 return 1;
00210 }
00211 return ht_uformat_viewer::symbol_handler(result, name);
00212 }
00213
00214
00215
00216
00217
00218 void ht_hex_file_sub::handlemsg(htmsg *msg)
00219 {
00220 if (msg->msg == msg_filesize_changed) {
00221 UINT s = file->get_size();
00222 fsize = s;
00223 return;
00224 }
00225 ht_hex_sub::handlemsg(msg);
00226 }
00227