Self reading/modification
I managed to get my gasp app working on it's parent process but now I need some help with getting it to access it's own memory (figures that it would be easier to get the parent process memory than it's own), once I have access on both I will test modifying the memory via a string I will print both before and after the expected modification to check it has been modified, anyways the code I'm using to open process memory is below, tell me if you see any problems and/or know of what to do when trying to access own memory, I might end up making specialized functions for self modification at this rate (which I would rather not).
Code:
void* proc_handle_wait( void *data ) {
proc_handle_t *handle = data;
int status = 0;
(void)pthread_detach( handle->thread );
while ( handle->waiting ) {
waitpid(handle->notice.entryId,&status,0);
if ( WIFEXITED(status) || WIFSIGNALED(status) ) {
handle->running = 0;
break;
}
}
handle->waiting = 0;
return data;
}
proc_handle_t* proc_handle_open( int *err, int pid )
{
char path[256] = {0};
proc_handle_t *handle;
long attach_ret = -1;
#ifdef PTRACE_SEIZE
int ptrace_mode = PTRACE_SEIZE;
#else
int ptrace_mode = PTRACE_ATTACH;
ERRMSG( ENOSYS,
"PTRACE_SEIZE not defined, defaulting to PTRACE_ATTACH");
#endif
attach_ret = ptrace( ptrace_mode, pid, NULL, NULL );
if ( attach_ret != 0 ) {
if ( err ) *err = errno;
return NULL;
}
if ( !(handle = calloc(sizeof(proc_handle_t),1)) ) {
if ( err ) *err = errno;
return NULL;
}
if ( !proc_notice_info( err, pid, &(handle->notice) ) ) {
proc_handle_shut( handle );
return NULL;
}
(void)sprintf( path, "/proc/%d/maps", pid );
if ( (handle->pagesFd = open(path,O_RDONLY)) < 0 ) {
proc_handle_shut( handle );
if ( err ) *err = errno;
ERRMSG( errno, "Couldn't open maps file" );
return NULL;
}
(void)sprintf( path, "/proc/%d/mem", pid );
if ( (handle->rdMemFd = open(path,O_RDONLY)) < 0 ) {
proc_handle_shut( handle );
if ( err ) *err = errno;
ERRMSG( errno, "Couldn't open mem file in read only mode" );
return NULL;
}
handle->wrMemFd = open(path,O_WRONLY);
handle->running = 1;
#if 0
if ( pid != (getpid()) ) {
if ( pthread_create( &(handle->thread),
NULL, proc_handle_wait, handle ) ) {
proc_handle_shut( handle );
ERRMSG( errno, "Couldn't create pthread to check for SIGKILL" );
return NULL;
}
handle->waiting = 1;
}
#endif
return handle;
}
void proc_handle_shut( proc_handle_t *handle ) {
/* Used only to prevent segfault from pthread_join, do nothing
* with it */
void *data;
/* Don't try to close NULL as that will segfault */
if ( !handle ) return;
/* Ensure thread closes before we release the handle it's using */
if ( handle->waiting ) {
handle->waiting = 0;
(void)pthread_join( handle->thread, &data );
}
/* Cleanup noticed info */
proc_notice_zero( &(handle->notice) );
/* None of these need to be open anymore */
if ( handle->rdMemFd >= 0 ) close( handle->rdMemFd );
if ( handle->wrMemFd >= 0 ) close( handle->wrMemFd );
if ( handle->pagesFd >= 0 ) close( handle->pagesFd );
/* Ensure that even if handle is reused by accident the most that
* can happen is a segfault */
(void)memset(handle,0,sizeof(proc_handle_t));
/* Ensure none of these are treated as valid in the above scenario*/
handle->rdMemFd = handle->wrMemFd = handle->pagesFd = -1;
/* No need for the handle anymore */
free(handle);
}
Edit: gotta go to work so any suggestions or bugs pointed out won't be tried until I get back.