Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


C# other process

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
NoMercy
Master Cheater
Reputation: 1

Joined: 09 Feb 2009
Posts: 289

PostPosted: Tue Jan 31, 2012 3:59 pm    Post subject: C# other process Reply with quote

Hello,

I would like to know if its possible to call functions from another process using c# with an .exe. I know the address in the other process and it's paramters + return type. The calling way etc.

I thought about creating a function with VirtualAllocEx and the use CreateRemoteThread on that, with the info for that function. But then I've to use pure bytes in my thread in the virtualalloc? Perhaps this does not even work or it's a lot of work.

Thanks for helping

Gez
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Tue Jan 31, 2012 11:22 pm    Post subject: Reply with quote

Using CreateRemoteThread method works fine. You may need to write a stub to handle the call with arguments etc. as well as to obtain any extended return info. But you should be able to use it fine.
_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
NoMercy
Master Cheater
Reputation: 1

Joined: 09 Feb 2009
Posts: 289

PostPosted: Wed Feb 01, 2012 12:46 pm    Post subject: Reply with quote

Oki, I've got this atm

Code:
[DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, UInt32 dwSize,
        UInt32 flAllocationType, UInt32 flProtect);

        [DllImport("kernel32.dll")]
        public static extern IntPtr CreateRemoteThread(
          IntPtr hProcess,
          IntPtr lpThreadAttributes,
          uint dwStackSize,
          IntPtr lpStartAddress,
          IntPtr lpParameter,
          uint dwCreationFlags,
          uint lpThreadId
        );

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
            byte[] lpBuffer, uint nSize, UIntPtr lpNumberOfBytesWritten);

        public Hook()
        {
            Process myProcess = null;

            myProcess = (from Process proc in Process.GetProcessesByName("Test")
                         select proc).FirstOrDefault();

            IntPtr ProcessHandle = myProcess.Handle;

            IntPtr Addr = VirtualAllocEx(ProcessHandle, IntPtr.Zero, 500, 0x1000, 0x40);
            int yy = Marshal.GetLastWin32Error();

            int addresstocall = 0x013C14B0;
            int callto = addresstocall - Addr.ToInt32() - 5;

            byte[] bytes = BitConverter.GetBytes(callto);

            byte[] result = new byte[6];
            result[0] = 0xe8;
            result[1] = bytes[0];
            result[2] = bytes[1];
            result[3] = bytes[2];
            result[4] = bytes[3];

            UIntPtr shit = new UIntPtr();
            bool x = WriteProcessMemory(ProcessHandle, Addr, result, 5, shit);
            if(x)
                Console.WriteLine("happy");

            CreateRemoteThread(ProcessHandle, (IntPtr) 0 , 0, Addr, (IntPtr) 0, 0, 0);
            int check = Marshal.GetLastWin32Error();
            bool lel = false;
        }


I open my own test.exe which has a function func1 at the addresstocall variable. Everything works fine till CreateRemoteThread. If i check the asm of the memory I allocate, it shows call Func1. But my test.exe crashes with an error.

Thanks
Back to top
View user's profile Send private message
Stylo
Grandmaster Cheater Supreme
Reputation: 3

Joined: 16 May 2007
Posts: 1073
Location: Israel

PostPosted: Wed Feb 01, 2012 1:20 pm    Post subject: Reply with quote

Why are you using VirtualAllocEx ?
I believe CreateRemoteThread would suffice for calling a function from another process.

_________________
Stylo
Back to top
View user's profile Send private message
NoMercy
Master Cheater
Reputation: 1

Joined: 09 Feb 2009
Posts: 289

PostPosted: Wed Feb 01, 2012 1:28 pm    Post subject: Reply with quote

Stylo wrote:
Why are you using VirtualAllocEx ?
I believe CreateRemoteThread would suffice for calling a function from another process.


But what if I want to pass a value to it? Or want the retrun value?
Back to top
View user's profile Send private message
Stylo
Grandmaster Cheater Supreme
Reputation: 3

Joined: 16 May 2007
Posts: 1073
Location: Israel

PostPosted: Wed Feb 01, 2012 11:11 pm    Post subject: Reply with quote

You can pass up to one parameter if you want through CreateRemoteThread, but if you're trying more than one you can use a struct but it's good as long as the called function knows how to handle that struct.
Other way is to inject a dll into the target process and call the function from there since it's in the process's memo space, and you can call it by using inline assembly.

_________________
Stylo
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Thu Feb 02, 2012 2:48 am    Post subject: Reply with quote

You can inject your own function stub to call a function that takes more then one argument. For example this is from one of my injection projects:

Code:

BYTE btUnloadCode[] = { // Thanks to WinJect For This :)
                                    0x55, // push ebp
                              0x8B, 0xEC, // mov ebp, esp
                                    0x51, // push ecx
0xC7, 0x45, 0xFC, 0x00, 0x00, 0x00, 0x00, // mov [ebp-04], 0
                        0x8B, 0x45, 0x08, // mov eax, [ebp+8]
                        0x83, 0xC0, 0x08, // add eax, 8
                                    0x50, // push eax
                        0x8B, 0x4D, 0x08, // mov ecx, [ebp+8]
                              0xFF, 0x11, // call dword ptr [ecx] ; Call GetModuleHandleA
                        0x89, 0x45, 0xFC, // mov [ebp-4], eax
                        0x8B, 0x55, 0xFC, // mov edx, [ebp-4]
                                    0x52, // push edx
                        0x8B, 0x45, 0x08, // mov eax, [ebp+8]
                        0xFF, 0x50, 0x04, // call dword ptr [eax+4] ; Call LdrUnloadDll
                        0x8B, 0x4D, 0x08, // mov ecx, [ebp+8]
      0x89, 0x81, 0x0C, 0x01, 0x00, 0x00, // mov [ecx+10c], eax
                              0x33, 0xC0, // xor eax, eax
                              0x8B, 0xE5, // mov esp, ebp
                                    0x5D, // pop ebp
                        0xC2, 0x04, 0x00  // ret 04
};


Which can be called like:

Code:
INJECT_API HRESULT __stdcall Eject( DWORD dwProcessId, char* tszModule )
{
   DWORD   dwProcId;      // Process Id
   DWORD   dwThreadId;      // Thread Id
   HANDLE   hProcess;      // Process Handle
   HANDLE   hThread;      // Process Thread Handle
   HANDLE   hRemoteThread;   // Remote Thread Handle
   LPVOID   lpAlloc;      // Allocated Library String And Params
   DWORD   dwExitCode;      // Remote Thread Exit Code
   FARPROC lpGetModHandA;   // GetModuleHandleA Address
   FARPROC lpLdrUnloadDll; // LdrUnloadDll Address

   // Valid Params?
   if( dwProcessId == 0 || !tszModule )
      return RETVAL_HRESULT_EFAIL;

   // Process Running?
   dwProcId = _IsProcRunning( dwProcessId );
   if( dwProcId == 0 )
      return RETVAL_HRESULT_EFAIL;

   // Module Path Exists?
   if( GetFileAttributes( tszModule ) == 0xFFFFFFFF )
      return RETVAL_HRESULT_EFAIL;

   // Obtain Access
   if( !_SetPrivilege() )
      return RETVAL_HRESULT_EFAIL;

   // Obtain Thread Id
   dwThreadId = _ThreadFromProcId( dwProcId );
   if( dwThreadId == 0 )
      return RETVAL_HRESULT_EFAIL;

   // Obtain API Addresses
   lpGetModHandA = GetProcAddress( GetModuleHandle( "kernel32" ), "GetModuleHandleA" );
   lpLdrUnloadDll = GetProcAddress( LoadLibrary( "ntdll" ), "LdrUnloadDll" );
   if( !lpGetModHandA || !lpLdrUnloadDll )
      return RETVAL_HRESULT_EFAIL;

   // Open Handles
   hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, dwProcId );
   hThread = OpenThread( THREAD_ALL_ACCESS, FALSE, dwThreadId );
   if( hProcess == 0 || hThread == 0 )
   {
      if( hProcess )
         CloseHandle( hProcess );
      if( hThread )
         CloseHandle( hThread );
      return RETVAL_HRESULT_EFAIL;
   }

   // Suspend Thread
   SuspendThread( hThread );
   Sleep( 100 );

   // Allocate Needed Memory
   lpAlloc = VirtualAllocEx( hProcess, 0, strlen( tszModule ) + sizeof( btUnloadCode ) + 10, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
   if( !lpAlloc )
   {
      ResumeThread( hThread );
      CloseHandle( hThread );
      CloseHandle( hProcess );
      return RETVAL_HRESULT_EFAIL;
   }

   // Write Params To Memory
   if( !WriteProcessMemory( hProcess, lpAlloc, &lpGetModHandA, 4, 0 ) ||
      !WriteProcessMemory( hProcess, ((BYTE*)lpAlloc)+4, &lpLdrUnloadDll, 4, 0 ) ||
      !WriteProcessMemory( hProcess, ((BYTE*)lpAlloc)+8, tszModule, strlen( tszModule ), 0 ) ||
      !WriteProcessMemory( hProcess, ((BYTE*)lpAlloc)+8+strlen( tszModule )+1, &btUnloadCode, sizeof( btUnloadCode ), 0 ) )
   {
      VirtualFreeEx( hProcess, lpAlloc, strlen( tszModule ) + sizeof( btUnloadCode ) + 10, MEM_DECOMMIT );
      ResumeThread( hThread );
      CloseHandle( hThread );
      CloseHandle( hProcess );
      return RETVAL_HRESULT_EFAIL;
   }

   // Create Remote Thread And Call Code Block
   hRemoteThread = CreateRemoteThread( hProcess, 0, 0, ( LPTHREAD_START_ROUTINE )( (DWORD)lpAlloc+strlen( tszModule )+9 ), lpAlloc, 0, 0 );
   if( hRemoteThread == 0 )
   {
      VirtualFreeEx( hProcess, lpAlloc, strlen( tszModule ) + sizeof( btUnloadCode ) + 10, MEM_DECOMMIT );
      ResumeThread( hThread );
      CloseHandle( hThread );
      CloseHandle( hProcess );
      return RETVAL_HRESULT_EFAIL;
   }

   // Wait For Thread To Finish And Get Exit Code
   WaitForSingleObject( hRemoteThread, INFINITE );
   GetExitCodeThread( hRemoteThread, &dwExitCode );
   CloseHandle( hRemoteThread );

   // Cleanup Allocated Memory
   VirtualFreeEx( hProcess, lpAlloc, strlen( tszModule ) + sizeof( btUnloadCode ) + 10, MEM_DECOMMIT );

   // Cleanup Handles
   ResumeThread( hThread );
   CloseHandle( hThread );
   CloseHandle( hProcess );
   
   // Did The Thread Execute Properly?
   if( !dwExitCode )
      return RETVAL_HRESULT_WARNING;

   // All Is Good :)
   return RETVAL_HRESULT_SOK;
}


You can do the same for internal functions of another process.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
NoMercy
Master Cheater
Reputation: 1

Joined: 09 Feb 2009
Posts: 289

PostPosted: Sat Feb 04, 2012 2:50 am    Post subject: Reply with quote

Thanks Wiccaan, but I don't understand what you did here

Code:
WriteProcessMemory( hProcess, lpAlloc, &lpGetModHandA, 4, 0 ) ||
      !WriteProcessMemory( hProcess, ((BYTE*)lpAlloc)+4, &lpLdrUnloadDll, 4, 0 ) ||
      !WriteProcessMemory( hProcess, ((BYTE*)lpAlloc)+8, tszModule, strlen( tszModule ), 0 ) ||
      !WriteProcessMemory( hProcess, ((BYTE*)lpAlloc)+8+strlen( tszModule )+1, &btUnloadCode, sizeof( btUnloadCode ), 0 ) )


You are writing the address of GetModHandleA and LdrUnloadDll to the first 2 addresses. In your assembly script you use these addresses to call them right? But

Code:
0x55, // push ebp
                              0x8B, 0xEC, // mov ebp, esp
                                    0x51, // push ecx
0xC7, 0x45, 0xFC, 0x00, 0x00, 0x00, 0x00, // mov [ebp-04], 0
                        0x8B, 0x45, 0x08, // mov eax, [ebp+8]
                        0x83, 0xC0, 0x08, // add eax, 8
                                    0x50, // push eax


Where is this for? Is this the basic function assembly?
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Sat Feb 04, 2012 4:17 am    Post subject: Reply with quote

Code:
   // Write Params To Memory
   if( !WriteProcessMemory( hProcess, lpAlloc, &lpGetModHandA, 4, 0 ) ||
      !WriteProcessMemory( hProcess, ((BYTE*)lpAlloc)+4, &lpLdrUnloadDll, 4, 0 ) ||
      !WriteProcessMemory( hProcess, ((BYTE*)lpAlloc)+8, tszModule, strlen( tszModule ), 0 ) ||
      !WriteProcessMemory( hProcess, ((BYTE*)lpAlloc)+8+strlen( tszModule )+1, &btUnloadCode, sizeof( btUnloadCode ), 0 ) )


This is writing each param to memory then writing the unload code afterward.

// Writes the address for GetModuleHandleA (This is written at the start of the new allocated memory.)
WriteProcessMemory( hProcess, lpAlloc, &lpGetModHandA, 4, 0 )

// Writes the address for LdrUnloadDll (This is written from the base of the new allocated memory +4.)
WriteProcessMemory( hProcess, ((BYTE*)lpAlloc)+4, &lpLdrUnloadDll, 4, 0 )

// Writes the module name to unload (This is written from the base of the new allocated memory +Cool
WriteProcessMemory( hProcess, ((BYTE*)lpAlloc)+8, tszModule, strlen( tszModule ), 0 )

// Writes the unload code (This is written from the base of the new allocated memory +9 +length of the module name.)
WriteProcessMemory( hProcess, ((BYTE*)lpAlloc)+8+strlen( tszModule )+1, &btUnloadCode, sizeof( btUnloadCode ), 0 ) )

// Calls the unload code
CreateRemoteThread( hProcess, 0, 0, ( LPTHREAD_START_ROUTINE )( (DWORD)lpAlloc+strlen( tszModule )+9 ), lpAlloc, 0, 0 );

lpAlloc is passed to CreateRemoteThread because it holds our params.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
NoMercy
Master Cheater
Reputation: 1

Joined: 09 Feb 2009
Posts: 289

PostPosted: Sat Feb 04, 2012 8:23 am    Post subject: Reply with quote

Wiccaan wrote:
Code:
   // Write Params To Memory
   if( !WriteProcessMemory( hProcess, lpAlloc, &lpGetModHandA, 4, 0 ) ||
      !WriteProcessMemory( hProcess, ((BYTE*)lpAlloc)+4, &lpLdrUnloadDll, 4, 0 ) ||
      !WriteProcessMemory( hProcess, ((BYTE*)lpAlloc)+8, tszModule, strlen( tszModule ), 0 ) ||
      !WriteProcessMemory( hProcess, ((BYTE*)lpAlloc)+8+strlen( tszModule )+1, &btUnloadCode, sizeof( btUnloadCode ), 0 ) )


This is writing each param to memory then writing the unload code afterward.

// Writes the address for GetModuleHandleA (This is written at the start of the new allocated memory.)
WriteProcessMemory( hProcess, lpAlloc, &lpGetModHandA, 4, 0 )

// Writes the address for LdrUnloadDll (This is written from the base of the new allocated memory +4.)
WriteProcessMemory( hProcess, ((BYTE*)lpAlloc)+4, &lpLdrUnloadDll, 4, 0 )

// Writes the module name to unload (This is written from the base of the new allocated memory +Cool
WriteProcessMemory( hProcess, ((BYTE*)lpAlloc)+8, tszModule, strlen( tszModule ), 0 )

// Writes the unload code (This is written from the base of the new allocated memory +9 +length of the module name.)
WriteProcessMemory( hProcess, ((BYTE*)lpAlloc)+8+strlen( tszModule )+1, &btUnloadCode, sizeof( btUnloadCode ), 0 ) )

// Calls the unload code
CreateRemoteThread( hProcess, 0, 0, ( LPTHREAD_START_ROUTINE )( (DWORD)lpAlloc+strlen( tszModule )+9 ), lpAlloc, 0, 0 );

lpAlloc is passed to CreateRemoteThread because it holds our params.


Thanks Very Happy I understand it now Smile
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites