aboutsummaryrefslogtreecommitdiff
path: root/ui.c
diff options
context:
space:
mode:
Diffstat (limited to 'ui.c')
-rw-r--r--ui.c167
1 files changed, 167 insertions, 0 deletions
diff --git a/ui.c b/ui.c
new file mode 100644
index 0000000..f114a41
--- /dev/null
+++ b/ui.c
@@ -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;
+}