Hey everyone.
I compiled it in C++ awhile back and have been injecting it lately with Winject... Works great and is amazing. BUT now I decided to create an injector in C# and inject the DLL from there... This is where the problems begin. The injector seems to work great, its just the DLLmain from the C++ code isnt getting called or something, as It doesent work when injected from the C# injector. Here is the injector source (C#):
Code:
using System.Diagnostics;
using System;
using System.Xml.Linq;
using System.Windows.Forms;
using System.Collections;
using System.Drawing;
using Microsoft.VisualBasic;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
namespace injectortest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[DllImport("kernel32")]
public static extern IntPtr CreateRemoteThread(
IntPtr hProcess,
IntPtr lpThreadAttributes,
uint dwStackSize,
UIntPtr lpStartAddress, // raw Pointer into remote process
IntPtr lpParameter,
uint dwCreationFlags,
out IntPtr lpThreadId
);
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(
UInt32 dwDesiredAccess,
Int32 bInheritHandle,
Int32 dwProcessId
);
[DllImport("kernel32.dll")]
public static extern Int32 CloseHandle(
IntPtr hObject
);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern bool VirtualFreeEx(
IntPtr hProcess,
IntPtr lpAddress,
UIntPtr dwSize,
uint dwFreeType
);
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true)]
public static extern UIntPtr GetProcAddress(
IntPtr hModule,
string procName
);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAllocEx(
IntPtr hProcess,
IntPtr lpAddress,
uint dwSize,
uint flAllocationType,
uint flProtect
);
[DllImport("kernel32.dll")]
static extern bool WriteProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
string lpBuffer,
UIntPtr nSize,
out IntPtr lpNumberOfBytesWritten
);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetModuleHandle(
string lpModuleName
);
[DllImport("kernel32", SetLastError = true, ExactSpelling = true)]
internal static extern Int32 WaitForSingleObject(
IntPtr handle,
Int32 milliseconds
);
public Int32 GetProcessId(String proc)
{
Process[] ProcList;
ProcList = Process.GetProcessesByName(proc);
return ProcList[0].Id;
}
public void InjectDLL(IntPtr hProcess, String strDLLName)
{
IntPtr bytesout;
// Length of string containing the DLL file name +1 byte padding
Int32 LenWrite = strDLLName.Length + 1;
// Allocate memory within the virtual address space of the target process
IntPtr AllocMem = (IntPtr)VirtualAllocEx(hProcess, (IntPtr)null, (uint)LenWrite, 0x1000, 0x40); //allocation pour WriteProcessMemory
// Write DLL file name to allocated memory in target process
WriteProcessMemory(hProcess, AllocMem, strDLLName, (UIntPtr)LenWrite, out bytesout);
// Function pointer "Injector"
UIntPtr Injector = (UIntPtr)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
if (Injector == null)
{
MessageBox.Show(" Injector Error! \n ");
// return failed
return;
}
// Create thread in target process, and store handle in hThread
IntPtr hThread = (IntPtr)CreateRemoteThread(hProcess, (IntPtr)null, 0, Injector, AllocMem, 0, out bytesout);
// Make sure thread handle is valid
if (hThread == null)
{
//incorrect thread handle ... return failed
MessageBox.Show(" hThread [ 1 ] Error! \n ");
return;
}
// Time-out is 10 seconds...
int Result = WaitForSingleObject(hThread, 10 * 1000);
// Check whether thread timed out...
if (Result == 0x00000080L || Result == 0x00000102L || Result == 0xFFFFFFFF)
{
/* Thread timed out... */
MessageBox.Show(" hThread [ 2 ] Error! \n ");
// Make sure thread handle is valid before closing... prevents crashes.
if (hThread != null)
{
//Close thread in target process
CloseHandle(hThread);
}
return;
}
// Sleep thread for 1 second
Thread.Sleep(1000);
// Clear up allocated space ( Allocmem )
VirtualFreeEx(hProcess, AllocMem, (UIntPtr)0, 0x8000);
// Make sure thread handle is valid before closing... prevents crashes.
if (hThread != null)
{
MessageBox.Show("Success");
//Close thread in target process
CloseHandle(hThread);
}
// return succeeded
return;
}
public void nject10n()
{
String dllnaem = "hacks.dll";
String pr0c3ssname = "iw3mp";
Int32 ProcID = GetProcessId(pr0c3ssname);
if (ProcID >= 0)
{
IntPtr hProcess = (IntPtr)OpenProcess(0x1F0FFF, 1,ProcID);
if (hProcess == null)
{
MessageBox.Show("OpenProcess() Failed!");
return;
}
else
InjectDLL(hProcess, dllnaem);
}
}
private void button1_Click(object sender, EventArgs e)
{
nject10n();
}
}
}
And the DLL Code
Code:
/*COD4 Chams Hack
Copyright (C) 2012 SystemFiles
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
// #include "check.cpp"
#include "Headers.h"
LONG WINAPI ExceptionHandler( EXCEPTION_POINTERS* ExceptionInfo );
BYTE OriginalBytes[5];
VOID SetBreakpoints()
{
AddVectoredExceptionHandler( rand() % 0xFFFFFF, ExceptionHandler );
CONTEXT Context = { CONTEXT_DEBUG_REGISTERS };
Context.Dr0 = Engine::DrawXModelSkinnedCachedOffset;
Context.Dr7 = 0x1;
SetThreadContext( GetCurrentThread(), &Context );
}
VOID MyDrawXModelSkinnedCached( INT a1, INT a2, INT a3 )
{
CHAR* ModelName;
_asm PUSHAD;
_asm MOV EBX, [EDI + 0xB8];
_asm MOV EAX, [EBX];
_asm MOV ModelName, EAX;
static BOOL bRemove = FALSE;
if( !bRemove )
{
DWORD Protect = 0x0;
VirtualProtect( ( VOID* )Engine::DrawXModelSkinnedCachedOffset, 5, PAGE_EXECUTE_READWRITE, &Protect );
for( INT i = 0; i < 5; i++ )
*( BYTE* )( Engine::DrawXModelSkinnedCachedOffset + i ) = OriginalBytes[i];
VirtualProtect( ( VOID* )Engine::DrawXModelSkinnedCachedOffset, 5, Protect, &Protect );
SetBreakpoints();
bRemove = TRUE;
}
if( Engine::D3DDevice != NULL && Engine::D3DDevice != NULL )
{
if( Tools::RedTexture == NULL || Tools::YellowTexture == NULL || Tools::SkyBlueTexture == NULL || Tools::GreenTexture == NULL )
{
Tools::GenerateTexture( Engine::D3DDevice, &Tools::RedTexture, D3DCOLOR_RGBA( 255, 0, 0, 255 ) );
Tools::GenerateTexture( Engine::D3DDevice, &Tools::YellowTexture, D3DCOLOR_RGBA( 255, 255, 0, 255 ) );
Tools::GenerateTexture( Engine::D3DDevice, &Tools::SkyBlueTexture, D3DCOLOR_RGBA( 0, 170, 255, 255 ) );
Tools::GenerateTexture( Engine::D3DDevice, &Tools::GreenTexture, D3DCOLOR_RGBA( 0, 255, 0, 255 ) );
}
if( !strstr( ModelName, "mi24p" ) && !strstr( ModelName, "weapon" ) && !strstr( ModelName, "cobra" ) )
{
if( strstr( ModelName, "sas" ) || strstr( ModelName, "usmc" ) )
{
Engine::D3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE );
Engine::D3DDevice->SetTexture( 0, Tools::YellowTexture );
Engine::DrawXModelSkinnedCached( a1, a2, a3 );
Engine::D3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE );
Engine::D3DDevice->SetTexture( 0, Tools::RedTexture );
}
else if( strstr( ModelName, "opforce" ) || strstr( ModelName, "arab" ) || strstr( ModelName, "head_suren" ) )
{
Engine::D3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE );
Engine::D3DDevice->SetTexture( 0, Tools::GreenTexture );
Engine::DrawXModelSkinnedCached( a1, a2, a3 );
Engine::D3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE );
Engine::D3DDevice->SetTexture( 0, Tools::SkyBlueTexture );
}
}
}
_asm POPAD;
Engine::DrawXModelSkinnedCached( a1, a2, a3 );
}
LONG WINAPI ExceptionHandler( EXCEPTION_POINTERS* ExceptionInfo )
{
if( ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP && ( DWORD )ExceptionInfo->ExceptionRecord->ExceptionAddress == Engine::DrawXModelSkinnedCachedOffset )
{
ExceptionInfo->ContextRecord->Eip = ( DWORD )MyDrawXModelSkinnedCached;
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
DWORD WINAPI HookThread( VOID* Arguments )
{
for( INT i = 0; i < 5; i++ )
OriginalBytes[i] = *( BYTE* )( Engine::DrawXModelSkinnedCachedOffset + i );
Engine::DrawXModelSkinnedCached = ( Engine::tDrawXModelSkinnedCached )Tools::JMPHook( ( BYTE* )Engine::DrawXModelSkinnedCachedOffset, ( BYTE* )MyDrawXModelSkinnedCached, 5 );
return 0;
}
//BOOL WINAPI DLLMAIN( HMODULE hModule, DWORD Reason, VOID* Reserved )
//
//
// CreateThread( NULL, 0, ( LPTHREAD_START_ROUTINE )HookThread, NULL, 0x0, NULL );
// return TRUE;
//}
BOOL WINAPI DllMain( HMODULE hModule, DWORD Reason, VOID* Reserved )
{
if( Reason == DLL_PROCESS_ATTACH )
{
CreateThread( NULL, 0, ( LPTHREAD_START_ROUTINE )HookThread, NULL, 0x0, NULL );
}
//if( Reason == DLL_THREAD_ATTACH )
//{
// CreateThread( NULL, 0, ( LPTHREAD_START_ROUTINE )HookThread, NULL, 0x0, NULL );
//}
//as you can see i was playing around with the thread calling after i got frustrated... it didnt work! :(
return TRUE;
}
Im pretty sure thats working great, Its just the DLL never activates. Do I need to create a pipe to the DLL and call DLLMain? Why isnt the DLLmain being executed at all?
Im a bit confused, and I have looked all around the net and havent found much information on this. Its hard to put into words to search for the problem like this, so thats why I finally decided to post here as a last resort. If theres a keyword name/search for this please let me know... I just dont know how to put my problem into words.
TL;DR
1. C++ DLL Successfully Works when injected with Winject
2. Doesent work with C# Injector, But No Errors Received from C# Injector
PS: I did an injector in Visual Basics similiar to the C# one and it injects fine also, just no chams... No Errors or anything.
Thanks! Any help would be greatly appreciated.