mirror of
https://github.com/GameHackingBook/GameHackingCode
synced 2026-06-08 11:08:54 +00:00
Initial commit
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{A20C8EDD-02C5-499E-8DB6-1CB8081FD62B}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>Chapter7_CodeInjection</RootNamespace>
|
||||
<ProjectName>Chapter7_CodeInjection</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(SolutionDir)\BuildTemp\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IntDir>$(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StructMemberAlignment>4Bytes</StructMemberAlignment>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StructMemberAlignment>4Bytes</StructMemberAlignment>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<FixedBaseAddress>
|
||||
</FixedBaseAddress>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main-codeInjection.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,173 @@
|
||||
#include <iostream>
|
||||
#include <windows.h>
|
||||
#include <tlhelp32.h>
|
||||
|
||||
|
||||
DWORD printStringManyTimes(int times, const char* string)
|
||||
{
|
||||
for (int i = 0; i < times; i++)
|
||||
printf(string);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void injectCodeUsingThreadInjection(HANDLE process, LPVOID func, int times, const char* string)
|
||||
{
|
||||
BYTE codeCave[20] = {
|
||||
0xFF, 0x74, 0x24, 0x04, // PUSH DWORD PTR[ESP+0x4]
|
||||
0x68, 0x00, 0x00, 0x00, 0x00, // PUSH 0
|
||||
0xB8, 0x00, 0x00, 0x00, 0x00, // MOV EAX, 0x0
|
||||
0xFF, 0xD0, // CALL EAX
|
||||
0x83, 0xC4, 0x08, // ADD ESP, 0x08
|
||||
0xC3 // RETN
|
||||
};
|
||||
|
||||
// copy values to the shellcode
|
||||
memcpy(&codeCave[5], ×, 4);
|
||||
memcpy(&codeCave[10], &func, 4);
|
||||
|
||||
|
||||
// allocate memory for the coe cave
|
||||
int stringlen = strlen(string) + 1;
|
||||
int fulllen = stringlen + sizeof(codeCave);
|
||||
LPVOID remoteString = VirtualAllocEx(process, NULL, fulllen, MEM_COMMIT, PAGE_EXECUTE);
|
||||
LPVOID remoteCave = (LPVOID)((DWORD)remoteString + stringlen);
|
||||
|
||||
// write the code cave
|
||||
WriteProcessMemory(process, remoteString, string, stringlen, NULL);
|
||||
WriteProcessMemory(process, remoteCave, codeCave, sizeof(codeCave), NULL);
|
||||
|
||||
// run the thread
|
||||
HANDLE thread = CreateRemoteThread(process, NULL, NULL,
|
||||
(LPTHREAD_START_ROUTINE)remoteCave,
|
||||
remoteString, NULL, NULL);
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
CloseHandle(thread);
|
||||
}
|
||||
|
||||
|
||||
DWORD GetProcessThreadID(HANDLE Process)
|
||||
{
|
||||
THREADENTRY32 entry;
|
||||
entry.dwSize = sizeof(THREADENTRY32);
|
||||
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
|
||||
|
||||
if (Thread32First(snapshot, &entry) == TRUE)
|
||||
{
|
||||
DWORD PID = GetProcessId(Process);
|
||||
while (Thread32Next(snapshot, &entry) == TRUE)
|
||||
{
|
||||
if (entry.th32OwnerProcessID == PID)
|
||||
{
|
||||
CloseHandle(snapshot);
|
||||
return entry.th32ThreadID;
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(snapshot);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void injectCodeUsingThreadRedirection(HANDLE process, LPVOID func, int times, const char* string)
|
||||
{
|
||||
BYTE codeCave[31] = {
|
||||
0x60, //PUSHAD
|
||||
0x9C, //PUSHFD
|
||||
0x68, 0x00, 0x00, 0x00, 0x00, // PUSH 0
|
||||
0x68, 0x00, 0x00, 0x00, 0x00, // PUSH 0
|
||||
0xB8, 0x00, 0x00, 0x00, 0x00, // MOV EAX, 0x0
|
||||
0xFF, 0xD0, // CALL EAX
|
||||
0x83, 0xC4, 0x08, // ADD ESP, 0x08
|
||||
0x9D, //POPFD
|
||||
0x61, //POPAD
|
||||
0x68, 0x00, 0x00, 0x00, 0x00, // PUSH 0
|
||||
0xC3 // RETN
|
||||
};
|
||||
|
||||
// allocate memory for the coe cave
|
||||
int stringlen = strlen(string) + 1;
|
||||
int fulllen = stringlen + sizeof(codeCave);
|
||||
LPVOID remoteString = VirtualAllocEx(process, NULL, fulllen, MEM_COMMIT, PAGE_EXECUTE);
|
||||
LPVOID remoteCave = (LPVOID)((DWORD)remoteString + stringlen);
|
||||
|
||||
// suspend the thread and query its control context
|
||||
DWORD threadID = GetProcessThreadID(process);
|
||||
HANDLE thread = OpenThread((THREAD_GET_CONTEXT | THREAD_SUSPEND_RESUME | THREAD_SET_CONTEXT), false, threadID);
|
||||
SuspendThread(thread);
|
||||
|
||||
CONTEXT threadContext;
|
||||
threadContext.ContextFlags = CONTEXT_CONTROL;
|
||||
GetThreadContext(thread, &threadContext);
|
||||
|
||||
// copy values to the shellcode (happens late because we need values from allocation)
|
||||
memcpy(&codeCave[3], &remoteString, 4);
|
||||
memcpy(&codeCave[8], ×, 4);
|
||||
memcpy(&codeCave[13], &func, 4);
|
||||
memcpy(&codeCave[25], &threadContext.Eip, 4);
|
||||
|
||||
|
||||
// write the code cave
|
||||
WriteProcessMemory(process, remoteString, string, stringlen, NULL);
|
||||
WriteProcessMemory(process, remoteCave, codeCave, sizeof(codeCave), NULL);
|
||||
|
||||
|
||||
//redirect the thread
|
||||
threadContext.Eip = (DWORD)remoteCave;
|
||||
threadContext.ContextFlags = CONTEXT_CONTROL;
|
||||
SetThreadContext(thread, &threadContext);
|
||||
ResumeThread(thread);
|
||||
|
||||
//clean
|
||||
CloseHandle(thread);
|
||||
}
|
||||
|
||||
DWORD WINAPI redirectionThread(LPVOID lpParam)
|
||||
{
|
||||
injectCodeUsingThreadRedirection((HANDLE)lpParam, &printStringManyTimes, 2, "redirected\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void LoadDll(HANDLE process, const wchar_t* dllPath)
|
||||
{
|
||||
// write the dll name to memory
|
||||
int namelen = wcslen(dllPath) + 1;
|
||||
LPVOID remoteString = VirtualAllocEx(process, NULL, namelen * 2, MEM_COMMIT, PAGE_EXECUTE);
|
||||
WriteProcessMemory(process, remoteString, dllPath, namelen * 2, NULL);
|
||||
|
||||
// get the address of GetModuleHandle()
|
||||
HMODULE k32 = GetModuleHandleA("kernel32.dll");
|
||||
LPVOID funcAdr = GetProcAddress(k32, "LoadLibraryW");
|
||||
|
||||
// create the thread
|
||||
HANDLE thread =
|
||||
CreateRemoteThread(process, NULL, NULL, (LPTHREAD_START_ROUTINE)funcAdr, remoteString, NULL, NULL);
|
||||
|
||||
// let the thread finish and clean up
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
CloseHandle(thread);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
|
||||
|
||||
// inject code into self using thread injection
|
||||
injectCodeUsingThreadInjection(proc, &printStringManyTimes, 2, "injected\n");
|
||||
|
||||
// inject code into self using thread re-direction
|
||||
// we need to do it from a secondary thread or else
|
||||
// the redirection code would redirect itself.. which
|
||||
// doesn't work
|
||||
CreateThread(NULL, 0, redirectionThread, proc, 0, NULL);
|
||||
|
||||
LoadDll(proc, L"Chapter7_CodeInjection_DLL.dll");
|
||||
|
||||
|
||||
while (true) // stay busy
|
||||
{
|
||||
Sleep(100);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user