Code:
#undef __cplusplus
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
typedef bool(*printProc_t)(int pid, char const *name);
#ifdef _WIN32
// omitted
#else
#include <unistd.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <dirent.h>
#include <sys/ptrace.h>
#define PP___STRING( VALUE ) #VALUE
#define PP__STRING( VALUE ) PP___STRING( VALUE )
#define PP_STRING( VALUE ) PP__STRING( VALUE )
typedef struct POSIX_PROC_
{
int pid;
int imem;
int omem;
char path[6 + ( CHAR_BIT * 2 )];
} POSIX_PROC;
int posixFindProc( char const *name )
{
// Check we can find process
DIR *dir = opendir( "/proc" );
if( !dir ) return 0;
// Gonna need this in a min
struct dirent *ent = NULL;
int pid = 0;
size_t len = 0;
char path[PATH_MAX] = "/proc/";
char line[LINE_MAX] = "";
FILE *file = NULL;
while( ( ent = readdir( dir ) ) )
{
if( !isdigit( *ent->d_name ) ) continue;
path[6] = '\0';
strcat( path, ent->d_name );
strcat( path, "/cmdline" );
file = fopen( path, "r" );
if( !file ) continue;
len = fread( line, 1, LINE_MAX, file );
if( line[ len ] == '\n' )
line[ len ] = '\0';
fclose( file );
if( strcasecmp( line, name ) == 0 )
{
sscanf( ent->d_name, "%d", &pid );
clodedir(dir);
return pid;
}
}
closedir(dir);
return 0;
}
bool posixEnumProc( printProc_t printProcCB )
{
if ( !printProcCB ) return 0;
// Check we can find process
DIR *dir = opendir( "/proc" );
if( !dir ) return 0;
// Gonna need this in a min
struct dirent *ent = NULL;
int pid = 0;
size_t len = 0;
char path[PATH_MAX] = "/proc/";
char line[LINE_MAX + 1] = "";
FILE *file = NULL;
while( ( ent = readdir( dir ) ) )
{
if( !isdigit( *ent->d_name ) ) continue;
path[6] = '\0';
strcat( path, ent->d_name );
strcat( path, "/cmdline" );
file = fopen( path, "r" );
if( !file ) continue;
len = fread( line, 1, LINE_MAX, file );
if( line[ len ] != '\n' ) ++len;
line[ len ] = '\0';
fclose( file );
strtok( line, " \n" );
sscanf( ent->d_name, "%d", &pid );
if ( *line != '/' && line[1] && !printProcCB( pid, line ) ) break;
}
closedir(dir);
return 1;
}
POSIX_PROC posixOpenProc( int pid, bool makeChild, int flags )
{
POSIX_PROC proc = {0};
proc.pid = pid;
if( pid <= 0 ) return proc;
char mem[6 + ( CHAR_BIT * 2 ) + 3 ] = {0};
sprintf( proc.path, "/proc/%d/", pid );
strcpy( mem, proc.path );
strcat( mem, "mem" );
proc.imem = open( mem, O_RDONLY );
proc.omem = open( mem, O_WRONLY );
return proc;
}
uintptr_t upseek( int fd, uintptr_t addr )
{
if( lseek( fd, 0, SEEK_SET ) <= 0 ) return 0;
while( addr > PTRDIFF_MAX )
{
if( lseek( fd, PTRDIFF_MAX, SEEK_CUR ) <= 0 )
return 0;
addr -= PTRDIFF_MAX;
}
return ( lseek( fd, addr, SEEK_CUR ) > 0 ) ? 1 : 0;
}
size_t posixRdProc( POSIX_PROC proc, uintptr_t addr, void *buff, size_t size )
{
if( proc.imem <= 0 || !upseek( proc.imem, addr ) ) return 0;
return read( proc.imem, buff, size );
}
size_t posixWrProc( POSIX_PROC proc, uintptr_t addr, void *buff, size_t size )
{
if( proc.omem <= 0 )
{
long result = ptrace( PTRACE_POKEDATA, proc.pid, addr, buff );
if( result == 0 )
ptrace( PTRACE_POKETEXT, proc.pid, addr, buff );
if( result == 0 )
ptrace( PTRACE_POKEUSER, proc.pid, addr, buff );
return result;
}
if( !upseek( proc.omem, addr ) ) return 0;
return write( proc.omem, buff, size );
}
POSIX_PROC posixShutProc( POSIX_PROC proc )
{
if( proc.imem > 0 ) close( proc.imem );
if( proc.omem > 0 ) close( proc.omem );
return ( POSIX_PROC ) {0};
}
bool posixKillProc( int fdProc )
{
return 0;
}
#define rawFindProc posixFindProc
#define rawExecProc posixExecProc
#define rawEnumProc posixEnumProc
#define rawOpenProc posixOpenProc
#define rawRdProc posixRdProc
#define rawWrProc posixWrProc
#define rawShutProc posixShutProc
#define rawKillProc posixKillProc
#define HPROC POSIX_PROC
#define RAW_IS_PROC_VALID( M_HPROC ) (M_HPROC.pid > 0)
#define RAW_PROC_O_THREAD 0
#define RAW_PROC_O_QUERY 0
#define RAW_PROC_O_EXEC 0
#define RAW_PROC_O_KILL 0
#define RAW_PROC_O_MEM_OP 0
#define RAW_PROC_O_READ 0
#define RAW_PROC_O_RDWR 0
#define RAW_PROC_O_WRITE 0
#define RAW_PROC_O_PAUSE 0
#define RAW_PROC_O_DEBUG 0
#endif
bool printProc( int pid, char const *name )
{
fprintf(stdout,"%08X: %s\n", pid, name );
//puts( name );
return 1;
}
int main( void )
{
if ( !rawEnumProc(printProc) )
return -1;
/*/
HPROC proc = rawOpenProc( rawFindProc( "codeblocks" ), 0, RAW_PROC_O_READ );
if( RAW_IS_PROC_VALID( proc ) )
{
proc = rawShutProc( proc );
return 0;
}
//*/
fgetc( stdin );
return 0;
}