Skip to content

Instantly share code, notes, and snippets.

@vesim987
Last active July 10, 2016 21:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vesim987/1c0df8d01e3018e74d9a9218353b9aef to your computer and use it in GitHub Desktop.
Save vesim987/1c0df8d01e3018e74d9a9218353b9aef to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <unistd.h>
//#include "guess_max_fn.c"
FILE* fd;
int max_id = 1;
int guess_max(double x, int N, int count) {
size_t* rbp = NULL;
asm ("mov %%rbp, %0"
: "=r" (rbp)
:);
// lets do it only with first loop iteration
if(count == 1) {
// We need to iterate between ques_max stack frame and main stack frame,
// and find file descriptor in local variables.
//
// How stacks would be looks in this situation on 32 bits platform? Something like this:
// [ebp+00] main_ebp(pointer to stack frame of main function)
// [ebp+04] return address //----------
// there starts arguments // ↑
// [ebp+08] double x // i should skip this but whatever
// [ebp+0C] int N // ↓
// [ebp+10] int count //----------
// local variables start here
// [ebp+14] int N ????
// ...
// [ebp+1C+x] FILE* f; //<--- we need to find this
// ...
// [main_ebp]
//
// How to check if variable is a file descriptor?
// Lets see the _IO_FILE declaration in libio.h:
// struct _IO_FILE {
// int _flags; /* High-order word is _IO_MAGIC; rest is flags. */
// ...
// };
// here we go, all what we need to do is check first word in _flags.
size_t* guess_max_rbp = rbp;
size_t* main_rbp = (size_t*)rbp[0];
// local_var is increasing by sizeof(void*) because stack should be alignment of pointer size
for(size_t* local_var = guess_max_rbp; local_var < main_rbp; local_var += sizeof(void*)) {
// local_var is a valid address? (dirty way for !IsBadCodePtr() from WinAPI)
if(write(1, local_var, 1) == 1) {
if((*local_var & 0xFFFF0000) == _IO_MAGIC) {
fd = (FILE*)local_var;
}
}
}
if(fd) {
//save stream position
long stream_position = ftell(fd);
//C&P from main
double real_max = x;
for(int count = 2; count <= N; count++) { //skip first value
double x;
fscanf(fd, "%lf", &x);
if (real_max < x) {
real_max = x;
max_id = count;
}
}
//restore stream position
fseek(fd, stream_position, SEEK_SET);
}
}
if(count == max_id)
return 1;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment