📄 blockop.cc
字号:
free(action); if (expr_const) string_destroy(&v); }};Object *create_blockop_str_context(File *file, FileOfs ofs, uint len, uint size, bool netendian, char *action){ ht_blockop_str_context *ctx = new ht_blockop_str_context(); ctx->file = file; ctx->ofs = ofs; ctx->len = len; ctx->size = size; ctx->netendian = netendian; ctx->action = strdup(action); ctx->i = 0; ctx->o = ofs; blockop_expr_is_const = true; // test if first eval works blockop_i = ctx->i; blockop_o = ctx->o; eval_scalar r; if (!eval(&r, action, blockop_func_eval, blockop_symbol_eval, file)) { const char *s; int p; get_eval_error(&s, &p); throw MsgfException("error evaluating '%s': %s at %d", action, s, p); } ctx->expr_const = blockop_expr_is_const; if (ctx->expr_const) { scalar_context_str(&r, &ctx->v); } scalar_destroy(&r); return ctx;}#define BLOCKOP_STR_MAX_ITERATIONS 1024bool blockop_str_process(Object *context, ht_text *progress_indicator){ char status[64]; ht_blockop_str_context *ctx = (ht_blockop_str_context*)context; if (ctx->expr_const) { ht_snprintf(status, sizeof status, "operating (constant string)... %d%% complete", (int)(((double)(ctx->o-ctx->ofs)) * 100 / ctx->len)); progress_indicator->settext(status); for (uint i=0; i < BLOCKOP_STR_MAX_ITERATIONS; i++) if (ctx->o < ctx->ofs + ctx->len) { uint s = ctx->v.len; if (ctx->o + s > ctx->ofs + ctx->len) s = ctx->ofs + ctx->len - ctx->o; ctx->file->seek(ctx->o); ctx->file->writex(ctx->v.value, s);/* !=s) { throw ht_io_exception("blockop_str(): write error at pos %08qx, size %08qx", ctx->o, s); }*/ ctx->o += s; } else { return false; } } else { ht_snprintf(status, sizeof status, "operating (variable string)... %d%% complete", (int)(((double)(ctx->o-ctx->ofs)) * 100 / ctx->len)); progress_indicator->settext(status); eval_scalar r; eval_str sr; for (uint i=0; i < BLOCKOP_STR_MAX_ITERATIONS; i++) if (ctx->o < ctx->ofs + ctx->len) { blockop_i = ctx->i; blockop_o = ctx->o; if (!eval(&r, ctx->action, blockop_func_eval, blockop_symbol_eval, ctx->file)) { const char *s; int p; get_eval_error(&s, &p); throw MsgfException("error evaluating '%s': %s at %d", ctx->action, s, p); } scalar_context_str(&r, &sr); scalar_destroy(&r); uint s = sr.len; if (ctx->o+s > ctx->ofs+ctx->len) s = ctx->ofs+ctx->len-ctx->o; ctx->file->seek(ctx->o); ctx->file->writex(sr.value, s);/* !=s) { throw ht_io_exception("blockop_str(): write error at pos %08x, size %08x", ctx->o, s); }*/ string_destroy(&sr); ctx->o += s; ctx->i++; } else { return false; } } return true;}/* * BLOCKOP INTEGER */class ht_blockop_int_context: public Object {public: File *file; FileOfs ofs; uint len; uint size; Endianess endian; char *action; uint i; FileOfs o; bool expr_const; uint64 v; ~ht_blockop_int_context() { free(action); }};Object *create_blockop_int_context(File *file, FileOfs ofs, uint len, uint size, Endianess endian, char *action){ ht_blockop_int_context *ctx = new ht_blockop_int_context(); ctx->file = file; ctx->ofs = ofs; ctx->len = len; ctx->size = size; ctx->endian = endian; ctx->action = ht_strdup(action); ctx->i = 0; ctx->o = ofs; blockop_expr_is_const = true; // test if first eval works blockop_i = ctx->i; blockop_o = ctx->o; eval_scalar r; eval_int ir; if (!eval(&r, action, blockop_func_eval, blockop_symbol_eval, file)) { const char *s; int p; get_eval_error(&s, &p); throw MsgfException("error evaluating '%s': %s at %d", action, s, p); } ctx->expr_const = blockop_expr_is_const; if (ctx->expr_const) { scalar_context_int(&r, &ir); ctx->v = ir.value; } scalar_destroy(&r); return ctx;}#define BLOCKOP_INT_MAX_ITERATIONS 1024bool blockop_int_process(Object *context, ht_text *progress_indicator){ ht_blockop_int_context *ctx = (ht_blockop_int_context*)context; char status[64]; if (ctx->expr_const) { ht_snprintf(status, sizeof status, "operating (constant integer)... %d%% complete", (int)(((double)(ctx->o-ctx->ofs)) * 100 / ctx->len)); progress_indicator->settext(status); byte ibuf[8]; createForeignInt64(ibuf, ctx->v, ctx->size, ctx->endian); ctx->file->seek(ctx->o); for (uint i=0; i < BLOCKOP_INT_MAX_ITERATIONS; i++) { if (ctx->o < ctx->ofs + ctx->len) { uint s = ctx->size; if (ctx->o + s > ctx->ofs + ctx->len) s = ctx->ofs + ctx->len - ctx->o; ctx->file->writex(ibuf, s); ctx->o += s; } else { return false; } } } else { ht_snprintf(status, sizeof status, "operating (variable integer)... %d%% complete", (int)(((double)(ctx->o-ctx->ofs)) * 100 / ctx->len)); progress_indicator->settext(status); eval_scalar r; eval_int ir; for (uint i=0; i < BLOCKOP_INT_MAX_ITERATIONS; i++) if (ctx->o < ctx->ofs + ctx->len) { blockop_o = ctx->o; blockop_i = ctx->i; if (!eval(&r, ctx->action, blockop_func_eval, blockop_symbol_eval, ctx->file)) { const char *s; int p; get_eval_error(&s, &p); throw MsgfException("error evaluating '%s': %s at %d", ctx->action, s, p); } scalar_context_int(&r, &ir); scalar_destroy(&r); ctx->v = ir.value; uint s = ctx->size; if (ctx->o+s > ctx->ofs+ctx->len) s = ctx->ofs + ctx->len - ctx->o; byte ibuf[8]; createForeignInt64(ibuf, ctx->v, ctx->size, ctx->endian); ctx->file->seek(ctx->o); ctx->file->writex(ibuf, s); ctx->o += s; ctx->i++; } else { return false; } } return true;}bool format_string_to_offset_if_avail(ht_format_viewer *format, byte *string, int stringlen, const char *string_desc, FileOfs *ofs){ if (string && *string && stringlen < 64) { char str[64]; memcpy(str, string, stringlen); str[stringlen] = 0; if (!format->string_to_offset(str, ofs)) { errorbox("%s: '%s' doesn't seem to be a valid offset", string_desc, str); return false; } return true; } return false;} void blockop_dialog(ht_format_viewer *format, FileOfs pstart, FileOfs pend){ Bounds b; b.w = 65; b.h = 15; b.x = (screen->w - b.w)/2; b.y = (screen->h - b.h)/2; ht_blockop_dialog *d=new ht_blockop_dialog(); d->init(&b, pstart, pend, 0); bool run = true; int r; while (run && (r = d->run(false)) != button_cancel) { switch (r) { case 100: dialog_eval_help(blockop_func_eval, blockop_symbol_eval, NULL); break; default: { ht_blockop_dialog_data t; ViewDataBuf vdb(d, &t, sizeof t); File *file = format->get_file(); baseview->sendmsg(cmd_edit_mode_i, file, NULL); if (file->getAccessMode() & IOAM_WRITE) { FileOfs start = pstart, end = pend; if (format_string_to_offset_if_avail(format, t.start.text, t.start.textlen, "start", &start) && format_string_to_offset_if_avail(format, t.end.text, t.end.textlen, "end", &end)) { if (end > start) { int esize = 0; int esizes[4] = {8, 4, 2, 1}; switch (t.mode.cursor_pos) { /* element type: byte */ case 0: esize++; /* element type: uint16 */ case 1: esize++; /* element type: uint32 */ case 2: esize++; /* element type: uint64 */ case 3: { char a[4096]; bin2str(a, t.action.text, MIN(sizeof a, t.action.textlen)); insert_history_entry((List*)getAtomValue(HISTATOM_EVAL_EXPR), a, NULL); char addr[128]; bin2str(addr, t.start.text, MIN(sizeof addr, t.start.textlen)); insert_history_entry((List*)getAtomValue(HISTATOM_GOTO), addr, NULL); bin2str(addr, t.end.text, MIN(sizeof addr, t.end.textlen)); insert_history_entry((List*)getAtomValue(HISTATOM_GOTO), addr, NULL); esize = esizes[esize]; Object *ctx = NULL; try { ctx = create_blockop_int_context(file, start, end-start, esize, little_endian, a); if (ctx) { /*bool b = */execute_process(blockop_int_process, ctx); } } catch (const Exception &e) { errorbox("error: %y", &e); } delete ctx; break; } /* element type: string */ case 4: { char a[256]; bin2str(a, t.action.text, MIN(sizeof a, t.action.textlen)); insert_history_entry((List*)getAtomValue(HISTATOM_EVAL_EXPR), a, NULL); char addr[128]; bin2str(addr, t.start.text, MIN(sizeof addr, t.start.textlen)); insert_history_entry((List*)getAtomValue(HISTATOM_GOTO), addr, NULL); bin2str(addr, t.end.text, MIN(sizeof addr, t.end.textlen)); insert_history_entry((List*)getAtomValue(HISTATOM_GOTO), addr, NULL); Object *ctx = NULL; try { ctx = create_blockop_str_context(file, start, end-start, esize, little_endian, a); if (ctx) { /*bool b = */execute_process(blockop_str_process, ctx); } } catch (const Exception &e) { errorbox("error: %y", &e); } delete ctx; break; } default: errorbox("mode %d not supported", t.mode.cursor_pos); } } else { errorbox("end offset must be greater than start offset"); } } } run = false; } } } d->done(); delete d;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -