 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
NoMercy Master Cheater
Reputation: 1
Joined: 09 Feb 2009 Posts: 289
|
Posted: Tue Jan 31, 2012 3:59 pm Post subject: C# other process |
|
|
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 |
|
 |
atom0s Moderator
Reputation: 205
Joined: 25 Jan 2006 Posts: 8587 Location: 127.0.0.1
|
Posted: Tue Jan 31, 2012 11:22 pm Post subject: |
|
|
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 |
|
 |
NoMercy Master Cheater
Reputation: 1
Joined: 09 Feb 2009 Posts: 289
|
Posted: Wed Feb 01, 2012 12:46 pm Post subject: |
|
|
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 |
|
 |
Stylo Grandmaster Cheater Supreme
Reputation: 3
Joined: 16 May 2007 Posts: 1073 Location: Israel
|
Posted: Wed Feb 01, 2012 1:20 pm Post subject: |
|
|
Why are you using VirtualAllocEx ?
I believe CreateRemoteThread would suffice for calling a function from another process.
_________________
Stylo |
|
| Back to top |
|
 |
NoMercy Master Cheater
Reputation: 1
Joined: 09 Feb 2009 Posts: 289
|
Posted: Wed Feb 01, 2012 1:28 pm Post subject: |
|
|
| 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 |
|
 |
Stylo Grandmaster Cheater Supreme
Reputation: 3
Joined: 16 May 2007 Posts: 1073 Location: Israel
|
Posted: Wed Feb 01, 2012 11:11 pm Post subject: |
|
|
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 |
|
 |
atom0s Moderator
Reputation: 205
Joined: 25 Jan 2006 Posts: 8587 Location: 127.0.0.1
|
Posted: Thu Feb 02, 2012 2:48 am Post subject: |
|
|
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 |
|
 |
NoMercy Master Cheater
Reputation: 1
Joined: 09 Feb 2009 Posts: 289
|
Posted: Sat Feb 04, 2012 2:50 am Post subject: |
|
|
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 |
|
 |
atom0s Moderator
Reputation: 205
Joined: 25 Jan 2006 Posts: 8587 Location: 127.0.0.1
|
Posted: Sat Feb 04, 2012 4:17 am Post subject: |
|
|
| 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 +
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 |
|
 |
NoMercy Master Cheater
Reputation: 1
Joined: 09 Feb 2009 Posts: 289
|
Posted: Sat Feb 04, 2012 8:23 am Post subject: |
|
|
| 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 +
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 I understand it now
|
|
| Back to top |
|
 |
|
|
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
|
|