Results 1 to 3 of 3
  1. #1
    .::SCHiM::.'s Avatar
    Join Date
    Sep 2010
    Gender
    male
    Posts
    733
    Reputation
    180
    Thanks
    880
    My Mood
    Twisted

    Interprocess Callback Class

    Hey guys, with this class you can register callbacks in a remote process. For those of you who don't know: a callback is like a number you leave behind if you want someone to call you. If you 'register' a callback this means that when a certain condition is true your function will be called (back).

    In this case the condition is execution of a certain piece of code. Just like a hook you can register a callback on a function you'd like to monitor.

    For example if you want to register a callback on the Sleep() function in Firefox this is how you'd do it with my class:

    Code:
    #include "RemoteCallback.h"
    #include <iostream>
    
    void Callback(){
    	std::cout<< "Got here!!!" << std::endl;
    return;
    }
    
    int main( int argc, char* argv ){
    
    	Remote_Callback* r_c = new Remote_Callback( "firefox.exe" );                                        // open the process and read all internal variables
    
    	void* Target = (void*) GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "Sleep" );     // find the address of sleep
    
    		r_c->Set_callback( Target, (DWORD*)&Callback );                                                 // register a callback on sleep to call void Callback( void )
    	
    			Sleep(5000);                                                                                           // wait for 5 seconds
    
    	delete r_c;                                                                                                      //remove the callback and all hooks in the remote process 
    
    
    	system("pause");
    return 0;
    }
    Currently this all works with a call to CreateRemoteThread() in the remote process which start a new thread on our callback function. I'm going to improve this be finding a quicker way to start execution in our own process. Another point I'm going to upgrade are arguments since the whole thing is kinda pointless now since you can't change anything in the target process.

    RemoteCallback.h

    Code:
    #ifndef CALLBACK_R_H
    #define CALLHACK_R_H
    
    #include <Windows.h>
    
    class Hook;
    
    class Remote_Callback{
    
    	HANDLE hProc_;
    	DWORD pid_;
    
    	void* r_ptr;
    
    	bool Remote_Write( void* , void* , int  );
    	bool Remote_Read( void* , void* , int  );
    	bool Remote_Alloc( void** , int  );
    	bool Remote_Free( void*, int );
    
    	bool Duplicate_Handle( HANDLE& h_my_proc );
    
    public:
    
    
    	Remote_Callback( HANDLE hProc );
    	Remote_Callback( DWORD PID );
    	Remote_Callback( char* ProcessName );
    	~Remote_Callback();
    
    	bool good();
    
    	const DWORD pid(){ return pid_; }
    	const HANDLE& hProc(){ return hProc_; }
    	
    	bool Set_callback( void* HookAddress , DWORD* CallbackAddress ); 
    	
    private:
    
    	friend class Hook;
    	Hook* First;
    	Hook* Second;
    	Hook* Third;
    
    };
    
    class Hook{
    
    	friend class Remote_Callback;
    
    	void* OrigionalBytes;
    	void* RemoteHookLocation;
    	int HookSize;
    
    	Remote_Callback* cb; 
    	
    public:
    	
    	Hook( Remote_Callback* Callback, void* HookTarget, void* NewLocation );
    	~Hook();
    
    };
    
    
    #endif
    RemoteCallback.cpp

    Code:
    #define _CRT_SECURE_NO_WARNINGS
    
    #include "RemoteCallback.h"
    #include <Windows.h>
    #include <Tlhelp32.h>
    
    unsigned char Callback_Bytecode[] = { 
    
    	0x6A, 0x00,							//     PUSH 0
    	0x6A, 0x00,							//     PUSH 0
    	0x6A, 0x00,							//     PUSH 0
    	0x68, 0x90, 0x90, 0x90, 0x90,		//     PUSH 0x90909090 -> callback address
    	0x6A, 0x00,							//     PUSH 0
    	0x6A, 0x00,							//     PUSH 0
    	0x68, 0x90, 0x90, 0x90, 0x90,		//     PUSH 0x90909090 -> hproc
    	0xE8, 0x90, 0x90, 0x90, 0x90,		//     CALL 0x90909090 -> create remote thread
    
    };
    
    #define bytecode_loc_callback 7
    #define bytecode_loc_hproc 16
    #define bytecode_loc_CreateThread 21
    
    unsigned char Call_Bytecode[] = {
    
    	0xE8, 0x00, 0x00, 0x00, 0x00
    	
    };
    
    unsigned char Jump_Bytecode[] = {
    
    	0xE9, 0x00, 0x00, 0x00, 0x00
    	
    };
    
    #define bytecode_loc_jcall 1
    
    Remote_Callback::Remote_Callback( HANDLE hProc ) : hProc_( hProc ), pid_( 1 ) {}
    
    Remote_Callback::Remote_Callback( DWORD Pid ) : hProc_ ( NULL ), pid_( Pid ) {
    
    	hProc_ = OpenProcess( PROCESS_ALL_ACCESS, false, Pid );
    		if( !hProc_ ) pid_ =  NULL;
    
    }
    
    Remote_Callback::Remote_Callback( char* ProcessName ) : hProc_( NULL ), pid_( NULL ) {
    
    	if( !ProcessName ) return; 
    	
    			HANDLE hSnap = CreateToolhelp32Snapshot( TH32CS_SNAPALL, NULL );
    
    				if( !hSnap ) return;
    		
    			PROCESSENTRY32 pEntry = { 0 };
    			pEntry.dwSize = sizeof( PROCESSENTRY32 );
    
    				if( Process32First( hSnap, &pEntry ) ){
    					
    						do{
    							char* str = new char[ MAX_PATH ];
    							wcstombs( str, pEntry.szExeFile, MAX_PATH );
    
    								if( !strcmp( str, ProcessName ) ) {
    									 pid_ = pEntry.th32ProcessID;
    									
    											hProc_ = OpenProcess( PROCESS_ALL_ACCESS, false, pid_ );
    							
    											if( !hProc_ ) pid_ = NULL;
    
    										delete [] str;
    									break;
    								}
    							delete [] str;
    						} while ( Process32Next( hSnap, &pEntry ) );
    
    
    
    				} 
    
    			CloseHandle( hSnap );
    
    
    }
    
    Remote_Callback::~Remote_Callback(){
    	if( r_ptr ) Remote_Free( r_ptr, sizeof( Callback_Bytecode ) + sizeof( Jump_Bytecode ) );
    	if( First ) delete First;
    	if( Second ) delete Second;
    	if( Third ) delete Third;
    	if( hProc_ ) CloseHandle( hProc_ );	
    }
    
    bool Remote_Callback::good(){
    	return (( pid_  ) && ( hProc_ ) ) ? true : false;
    }
    
    bool Remote_Callback::Remote_Write( void* Location, void* Data, int Length ){
    
    	if( good() ){
    
    		if( !WriteProcessMemory( hProc_, Location, Data, Length, NULL ) ) return false;
    
    	} else return false;
    
    return true;
    }
    
    bool Remote_Callback::Remote_Read( void* Location, void* Data, int Length ){
    
    	if( good() ){
    
    		if( !ReadProcessMemory( hProc_, Location, Data, Length, NULL ) ) return false;
    
    	} else return false;
    
    return true;
    }
    
    bool Remote_Callback::Remote_Alloc(  void** Ptr, int Length ) {
    		
    	if( good() ){
    
    		*Ptr = VirtualAllocEx( hProc_, NULL, Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
    
    			if( !*Ptr ) return false;
    
    	} else return false;
    
    return true;
    }
    
    bool Remote_Callback::Remote_Free( void* Ptr, int Length ){
    
    	if( good() ){
    
    		if( !VirtualFreeEx( hProc_, Ptr, Length, MEM_RELEASE ) ) return false;
    
    	} else return false;
    
    return true;
    }
    bool Remote_Callback::Duplicate_Handle( HANDLE& h_my_proc ){
    
    	if( good() ) {
    
    			if(
    				!DuplicateHandle( 
    								 GetCurrentProcess(),
    								 GetCurrentProcess(),
    								 hProc_,
    								 &h_my_proc,
    								 PROCESS_ALL_ACCESS,
    								 false,
    								 NULL
    								 )
    			) return false;
    
    	} else return false;
    
    return true;
    }
    
    bool Remote_Callback::Set_callback( void* HookAddress, DWORD* CallbackAddress ){
    		
    	int Lenght = sizeof( Callback_Bytecode );
    
    			if( Remote_Alloc( &r_ptr, Lenght + sizeof( Jump_Bytecode )  ) ){
    
    					*(DWORD**)  &Callback_Bytecode[ bytecode_loc_callback ] = CallbackAddress;
    
    					HANDLE *phProc = (HANDLE*) &Callback_Bytecode[ bytecode_loc_hproc ];
    
    					Duplicate_Handle( *phProc );
    
    					*(FARPROC*) &Callback_Bytecode[ bytecode_loc_CreateThread ] = (FARPROC)( (int) GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "CreateRemoteThread" ) - ( (int)r_ptr + (bytecode_loc_CreateThread-1) + 5)  );
    														
    						if( Remote_Write( r_ptr, (void*) &Callback_Bytecode[0], Lenght ) ){
    						
    								First = new Hook( this, HookAddress, r_ptr );
    								Second = new Hook( this, (void*)( (int) r_ptr + Lenght ), First->OrigionalBytes );
    								Third = new Hook( this, (void*)( (int) First->OrigionalBytes + sizeof( Jump_Bytecode ) ), (void*) ((int) HookAddress + sizeof( Jump_Bytecode )) ); 
    
    						} else return false;				
    					
    			} else return false;
    
    return true;
    }
    
    Hook::Hook( Remote_Callback* Callback, void* HookLocation, void* NewLocation ) : HookSize( sizeof( Call_Bytecode ) ) , OrigionalBytes( NULL ), RemoteHookLocation( NULL ), cb( Callback ) {
    
    	if( !HookLocation || !NewLocation ) return;
    
    		if( cb->Remote_Alloc( &OrigionalBytes, 2*HookSize ) ){
    
    			char* TempBuffer = new char[ HookSize ];
    
    				if( cb->Remote_Read( HookLocation, (void*)TempBuffer, HookSize ) ){
    
    						if( cb->Remote_Write( OrigionalBytes, (void*) TempBuffer, HookSize ) ){
    						
    							*(void**) &Jump_Bytecode[ bytecode_loc_jcall ] = (void*) ( (int) NewLocation - (int) HookLocation - 5 );
    						
    								 cb->Remote_Write( HookLocation, (void*) &Jump_Bytecode[0], HookSize );
    
    								 RemoteHookLocation = HookLocation;
    
    						} else { delete [] TempBuffer; return; }
    
    				} else{ delete [] TempBuffer; return; }
    
    
    			delete [] TempBuffer;
    
    		} else return;
    		
    return;
    }
    
    Hook::~Hook(){
    
    	if( OrigionalBytes ) {
    
    			if( RemoteHookLocation ){
    					
    					char* Buffer = new char[ HookSize ];
    
    						if( cb->Remote_Read( OrigionalBytes, (void*) Buffer, HookSize ) ){
    
    								cb->Remote_Write( RemoteHookLocation, (void*) Buffer, HookSize );
    
    						}
    
    					delete [] Buffer;
    
    			}
    
    		cb->Remote_Free( OrigionalBytes, 2*HookSize );
    	}
    
    }
    Last edited by .::SCHiM::.; 02-16-2012 at 01:40 PM.

    I'm SCHiM

    Morals derive from the instinct to survive. Moral behavior is survival behavior above the individual level.

    Polymorphic engine
    Interprocess callback class
    SIN
    Infinite-precision arithmetic
    Hooking dynamic linkage
    (sloppy)Kernel mode Disassembler!!!

    Semi debugger




  2. The Following 4 Users Say Thank You to .::SCHiM::. For This Useful Post:

    giniyat101 (06-27-2012),Hassan (02-17-2012),Hell_Demon (02-17-2012),megamandos (04-02-2012)

  3. #2
    258456's Avatar
    Join Date
    May 2010
    Gender
    male
    Location
    ghjghj
    Posts
    1,222
    Reputation
    18
    Thanks
    300
    My Mood
    Relaxed
    Well as usual with all ur posts I m impressed and I learned a lot after studying ur code. Great job.

  4. #3
    Hell_Demon's Avatar
    Join Date
    Mar 2008
    Gender
    male
    Location
    I love causing havoc
    Posts
    3,976
    Reputation
    343
    Thanks
    4,320
    My Mood
    Cheeky
    Should be able to rep more then once >:
    Ah we-a blaze the fyah, make it bun dem!

Similar Threads

  1. what it's like to have religion class
    By ace76543 in forum Spammers Corner
    Replies: 7
    Last Post: 12-09-2006, 04:16 PM
  2. This is what math class does to you
    By apitite.for.distruction in forum Art & Graphic Design
    Replies: 14
    Last Post: 10-28-2006, 11:44 AM
  3. Guild Wars New Classes
    By Chronologix in forum General Gaming
    Replies: 24
    Last Post: 07-23-2006, 08:46 AM
  4. Heavy Weapons Class mine bug. I had no idea.
    By NukeAssault in forum General Gaming
    Replies: 2
    Last Post: 07-20-2006, 06:54 AM
  5. [Tutorial]Change class without respawn
    By vir2000 in forum Game Hacking Tutorials
    Replies: 0
    Last Post: 01-04-2006, 01:47 PM