This project injects a payload into a process so it can read and write memory for us,
so you can work with memory without opening or duplicating new handles.
Usage:
- load the payload with proxy::init()
- read and write with proxy::write(address, new value) and proxy::read(address)
- Enable debug privileges
- Find a process that already has a handle to the target
- Locate where that handle is stored in memory
- Allocate memory in the target process
- Inject payload + shellcode
- Communicate with the payload to read/write memory
int proxy::init(ULONG accessMask, LPCSTR windowName, bool debug)
Main entry point. Executes the full chain.
Parameters
accessMask: the permissions we are looking forwindowName: the window the handle should point todebug: true or false, depending on whether we want to see what the program is doing
Returns
1→ success2→ failed enabling SeDebugPrivilege3→ failed finding process with handle4→ failed finding handle address5→ failed allocating memory6→ failed injecting payload
bool proxy::enableSeDebugPrivilege()
Enables SeDebugPrivilege to allow interaction with external processes.
int proxy::findProcessWithHandle(
ULONG accessMask,
LPCSTR windowName,
DWORD* processPIDBuffer,
HANDLE* duplicatedHandleBuffer,
USHORT* originalHandleValue
)
Finds a process that already has a handle to the target window.
Parameters
accessMask: set the permissions you are looking forwindowName: "Counter - Strike 2"processPIDBuffer: pointer to a DWORD that will receive the PID of the process holding the handleduplicatedHandleBuffer: pointer to a HANDLE that will receive the duplicated handle (optional)originalHandleValue: pointer to a USHORT that will receive the original handle value
int proxy::findAddressWithHandle(
HANDLE handle,
DWORD pid,
uintptr_t* foundAtAddress,
LPCSTR windowName
)
Searches inside the process memory to find where the handle is stored.
Parameters
handle: the handle we are looking forpid: the PID of the process where we are searchingfoundAtAddress: pointer to a uintptr_t that will contain the address where the handle is storedwindowName: the window the handle should point to
int proxy::prepareCodeInjection(
DWORD pid,
LPVOID* rShellCodeBaseAddress,
LPVOID* wShellCodeBaseAddress,
LPVOID* rBufferBaseAddress,
LPVOID* wBufferBaseAddress,
LPVOID* structBaseAddress
)
Allocates memory in the target process.
Parameters
pid: PID of the target process that has the handlerShellCodeBaseAddress: pointer that will receive the base address where read shellcode is allocatedwShellCodeBaseAddress: pointer that will receive the base address where write shellcode is allocatedrBufferBaseAddress: pointer that will receive the base address where read values are storedwBufferBaseAddress: pointer that will receive the base address where values to write are storedstructBaseAddress: pointer that will receive the base address where the payload struct is stored
Allocations
int payload::load(
DWORD pid,
uintptr_t readShellCodeBaseAddress,
uintptr_t handleAddress,
uintptr_t readBufferAddress,
uintptr_t structBaseAddress
)
Injects the payload into the target process.
Parameters
pid: PID of the target process that has the handlereadShellCodeBaseAddress: address where the shellcode was allocatedhandleAddress: address where the process stores the desired handlereadBufferAddress: address where read values are storedstructBaseAddress: address where the payload struct was allocated
- Uses undocumented NT APIs (
NtQuerySystemInformation) - Needs SeDebugPrivilege
- Assumes target window exists
- Do not use on software you don’t own or don’t have permission to analyze