/*
 В Windows нет прямого аналога POSIX-сигналов, signal(SIGSEGV)
заменяется на SetUnhandledExceptionFilter (обработка SEH).
Cтандартный пакет strconv для парсинга hex-строк, так как Go
требует явной конвертации типов вместо магических методов Python.
*/

// 0x00007FF76AB1154C(win) - 0x00007FF76AB11657(main)
//  rmb -> search for -> current module -> string references

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

LONG WINAPI ExceptionFilter(EXCEPTION_POINTERS *ExceptionInfo) {
  if (ExceptionInfo->ExceptionRecord->ExceptionCode ==
      EXCEPTION_ACCESS_VIOLATION) {
    printf("Segfault Occurred, incorrect address.\n");
    ExitProcess(0);
  }
  return EXCEPTION_CONTINUE_SEARCH;
}

void win() {
  HANDLE hFile;
  char buffer[256];
  DWORD bytesRead;

  printf("You won!\n");

  hFile = CreateFileA("flag.txt", GENERIC_READ, FILE_SHARE_READ, NULL,
                      OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if (hFile == INVALID_HANDLE_VALUE) {
    printf("Cannot open file.\n");
    ExitProcess(0);
  }

  if (ReadFile(hFile, buffer, sizeof(buffer) - 1, &bytesRead, NULL) &&
      bytesRead > 0) {
    buffer[bytesRead] = '\0';
    printf("%s", buffer);
  }
  printf("\n");

  CloseHandle(hFile);
}

int main() {
  SetUnhandledExceptionFilter(ExceptionFilter);

  setvbuf(stdout, NULL, _IONBF, 0);

  printf("Address of main: %p\n", &main);

  unsigned long long val;
  printf("Enter the address to jump to, ex => 0x12345: ");

  scanf("%llx", &val);
  printf("Your input: %llx\n", val);

  void (*foo)(void) = (void (*)())val;
  foo();

  return 0;
}
