diff options
Diffstat (limited to 'ui.c')
-rw-r--r-- | ui.c | 167 |
1 files changed, 167 insertions, 0 deletions
@@ -0,0 +1,167 @@ +#define _POSIX_C_SOURCE 200809L + +#include <ctype.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <unistd.h> +#include <math.h> + +#include <ncurses.h> + +#define LINE_LEN 0x10 + +// int screen_height, screen_width; + +struct screen { + WINDOW *lineno, *hex, *chr; + int top_address; + void *mem; + size_t mem_len; + int hx, hy; +} screen = { + .hx = -1, .hy = -1, +}; + +void draw_lines() { + for (int y = 0; y < LINES; y++) { + mvwprintw(screen.lineno, y, 0, "%08x:", screen.top_address + y * LINE_LEN); + wrefresh(screen.lineno); + } +} + +void draw_hex() { + for (int y = 0; y < LINES; y++) { + for (int x = 0; x < LINE_LEN; x++) { + if (screen.hy == y && screen.hx == x) { + wattron(screen.hex, A_REVERSE); + } + mvwprintw(screen.hex, y, x * 2 + (x/2), "%02x", + 0xFF & ((char*) screen.mem)[screen.top_address + y * LINE_LEN + x]); + if (screen.hy == y && screen.hx == x) { + wattroff(screen.hex, A_REVERSE); + } + } + wrefresh(screen.hex); + } +} + +void draw_chr() { + for (int y = 0; y < LINES; y++) { + for (int x = 0; x < LINE_LEN; x++) { + if (screen.hy == y && screen.hx == x) { + wattron(screen.chr, A_REVERSE); + } + char c = ((char*) screen.mem)[screen.top_address + y * LINE_LEN + x]; + mvwprintw(screen.chr, y, x, "%c", isprint(c) ? c : '.'); + if (screen.hy == y && screen.hx == x) { + wattroff(screen.chr, A_REVERSE); + } + } + wrefresh(screen.chr); + } +} + +void draw_screen() { + + draw_lines(); + draw_hex(); + draw_chr(); + /* TODO end at end of file */ +} + +int main() { + + /* Terminal supporting mouse movements */ + setenv("TERM", "xterm-1003", true); + + initscr(); + clear(); + noecho(); + cbreak(); + curs_set(0); + + start_color(); + + // getmaxyx(stdscr, screen_height, screen_width); + + keypad(stdscr, true); + + screen.lineno = newwin(0, 10, 0, 0); + screen.hex = newwin(0, (int) ceil(LINE_LEN * 2.5), 0, 10); + screen.chr = newwin(0, LINE_LEN, 0, 10 + (int) ceil(LINE_LEN * 2.5)); + + int fd = open("payload.gz", O_RDONLY); + struct stat statbuf; + if (fstat(fd, &statbuf) == -1) { + goto end; + } + screen.mem_len = statbuf.st_size; + screen.mem = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0); + close(fd); + + mousemask(ALL_MOUSE_EVENTS|REPORT_MOUSE_POSITION, NULL); + + refresh(); + + draw_screen(); + + int ch; + MEVENT event; + while (1) { + ch = wgetch(stdscr); + switch (ch) { + case KEY_MOUSE: + wmove(stdscr, 0, 0); + switch (getmouse(&event)) { + case OK: + if (event.bstate & BUTTON4_PRESSED) { + screen.top_address -= LINE_LEN; + } + if (event.bstate & BUTTON5_PRESSED) { + screen.top_address += LINE_LEN; + } + + if (event.x >= 10 && event.x < 10 + (int) ceil(LINE_LEN * 2.5)) { + screen.hx = (int) ((event.x - 10) / 2.5); + screen.hy = event.y; + } else if (event.x >= 10 + (int) ceil(LINE_LEN * 2.5) && event.x < (int) ceil(LINE_LEN * 2.5) + 10 + LINE_LEN) { + screen.hx = event.x - (10 + (int) ceil(LINE_LEN * 2.5)); + screen.hy = event.y; + } else { + screen.hx = -1; + screen.hy = -1; + } + + draw_screen(); + break; + case ERR: + // wprintw(win, "err"); + break; + } + draw_screen(); + refresh(); + break; + case KEY_RESIZE: + wresize(screen.lineno, LINES, 0); + wresize(screen.hex, LINES, 0); + wresize(screen.chr, LINES, 0); + draw_screen(); + mvprintw(0, 0, "%ix%i", COLS, LINES); + refresh(); + break; + case KEY_ENTER: + goto end; + } + } + +end: + munmap(screen.mem, 0); + delwin(screen.lineno); + delwin(screen.hex); + delwin(screen.chr); + endwin(); + return 0; +} |