I found a C++ snippet that does the same as my Delphi D-Jector which doesn't use CreateRemoteThread API, I use this APC method to advoid common dections as most AV's and game hack detections tend to hook the CreateRemoteThread API to detect if injection methods is being used, while this type detection is pretty lame for the AV company or Game company, it still can be a pain in the ass unhooking that API just so your injection code works. Anyway I just wanted to share my injection method I use with you guys in a form thats understandable (C++ as 99.9% of programmers here use). there is also some nice little side benefits of using APC as opposed to CreateRemoteThread and that is it will work on ALL windows OS which makes your injector a true multi windows OS injector.
//Edit
[highlight=C++]
// Code Injection using APC
// Creative Commons - Aaron Burrow
#define _WIN32_WINNT 0x501
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <Tlhelp32.h>
VOID CALLBACK apc_me(ULONG_PTR param);
BOOL Get_Thread_ID(LPSTR proc_name, LPDWORD tid, LPDWORD pid);
BOOL Apply_And_Execute_APC(DWORD tid, DWORD pid, VOID CALLBACK (*function)(ULONG_PTR), ULONG_PTR arg, DWORD size);
INT main(INT argc, LPSTR* argv)
{
DWORD data = 10, tid, pid;
HANDLE thread_handle, process_handle;
LPVOID addr;
SIZE_T size;
if (Get_Thread_ID("t.exe", &tid, &pid)) {
Apply_And_Execute_APC(tid, pid, apc_me, 10, 500);
}
return 0;
}
// Just an example APC function
VOID CALLBACK apc_me(ULONG_PTR param)
{
*((INT*)0x7FFD6000) = 0xDEADBEEF;
// __asm__ ("int $0x3\n");
return;
}
/*
Get the thread id for some thread running in proc_name as
well as the process id;
@proc_name: The name of the process to get infos on.
@tid: Stores the thread id.
@pid: Stores the process id.
return: FALSE on failure, TRUE on success.
*/
BOOL Get_Thread_ID(LPSTR proc_name, LPDWORD tid, LPDWORD pid)
{
HANDLE snapshot = NULL;
PROCESSENTRY32 proc_entry;
THREADENTRY32 thread_entry;
BOOL found = FALSE, test;
snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snapshot == INVALID_HANDLE_VALUE)
goto cleanup_exit;
proc_entry.dwSize = sizeof(PROCESSENTRY32);
test = Process32First(snapshot, &proc_entry);
if (test == FALSE)
goto cleanup_exit;
do {
if (!(strcmp(proc_entry.szExeFile, proc_name))) {
*pid = proc_entry.th32ProcessID;
found = TRUE;
break;
}
} while (Process32Next(snapshot, &proc_entry));
if (found == FALSE)
goto cleanup_exit;
CloseHandle(snapshot);
snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (snapshot == INVALID_HANDLE_VALUE)
goto cleanup_exit;
thread_entry.dwSize = sizeof(THREADENTRY32);
test = Thread32First(snapshot, &thread_entry);
if (test == FALSE)
goto cleanup_exit;
found = FALSE;
do {
if (thread_entry.th32OwnerProcessID == *pid) {
*tid = thread_entry.th32ThreadID;
found = TRUE;
break;
}
} while(Thread32Next(snapshot, &thread_entry));
return TRUE;
cleanup_exit:
if (snapshot)
CloseHandle(snapshot);
return FALSE;
}
/*
Responsible for writing the function to the remote address space
as well as putting it into the threads APC queue.
@tid: Thread id of the thread to execute the APC.
@pid: Process id of the process the thread is in.
@Function: The actual APC.
@arg: An argument to be passed to the APC.
@size: The size of the APC.
return: FALSE on failure, TRUE on success.
*/
BOOL Apply_And_Execute_APC(DWORD tid, DWORD pid, VOID CALLBACK (*function)(ULONG_PTR), ULONG_PTR arg, DWORD size)
{
HANDLE thread_handle = NULL, process_handle = NULL;
LPVOID addr;
BOOL test;
DWORD out_size;
thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, tid);
if (!thread_handle)
goto cleanup_exit;
process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (!process_handle)
goto cleanup_exit;
addr = VirtualAllocEx(process_handle, NULL, 500, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!addr)
goto cleanup_exit;
test = WriteProcessMemory(process_handle, addr, (LPCVOID)function, size, &out_size);
if (test == FALSE)
goto cleanup_exit;
test = QueueUserAPC((PAPCFUNC)addr, thread_handle, arg);
if (!test)
goto cleanup_exit;
CloseHandle(process_handle);
CloseHandle(thread_handle);
return TRUE;
cleanup_exit:
if (process_handle)
CloseHandle(process_handle);
if (thread_handle)
CloseHandle(thread_handle);
return FALSE;
}
[/highlight]
check it out here
********* = "word press" without the quotes and space, some sort of forum filtering in actionCode:https://burrowscode.*********.com/2010/08/05/injecting-code-with-asynchronous-procedure-calls/
Last edited by Departure; 03-26-2011 at 09:46 PM. Reason: added snippet to topic
Upload as attachment?
No I do not make game hacks anymore, please stop asking.
Its a snippet not an attachment, but yeah go ahead and create C++ example application for the users here.
Yea someone posted this in C++ section claiming it as his
Whada fail idiot
Typical...
Anyway I only wanted to make a point of using APC methods for injection, it has multiple benefits over the standard CreateRemoteThread. For Delphi I had to study msdn about the function and then trial an error to get it working, too bad I didn't see this C++ snippet before as it would have made my life easier when coding a delphi implementation.