|
You last visited: Today at 11:38
Advertisement
Microsoft Detours 2.1
Discussion on Microsoft Detours 2.1 within the CO2 Programming forum part of the Conquer Online 2 category.
02/28/2011, 14:13
|
#1
|
elite*gold: 20
Join Date: Aug 2005
Posts: 1,734
Received Thanks: 1,001
|
Microsoft Detours 2.1
When I was working on a proxy a while ago I needed a way redirect the connections from conquer client to my proxy. There is a couple of ways to achieve this but I choose detours (2.1). However I noticed that there was a lack of tutorials on how to actually start using Microsoft detours (or I couldn't use Google properly, which is also possible  ). So here's a little step-by-step tutorial how to start using them and I will also show how to detour Connect and ShellExecute functions.
Step 1 - Download the detours package
You can download the detours package from  . Scroll down a bit and you should see Detours Express 2.1 this is the version you should download (unless you plan to get a license for it, which costs a "few" dollars.)
Step 2 - Install the detours package
Installing detours is pretty much the same as installing some other program. Just follow the instructions and unless you know what you're doing, don't change the installation directory. By default it should be C:\Program Files\Microsoft Research\Detours Express 2.1
Step 3 - Compiling the detours package
There's basically two ways to compile the detours package. The first way is to use program called "nmake" (which didn't work for me so we're not discussing it :P). The second way is to compile it using a C++ compiler. I'll be using Visual Studio 2010.
What you should now do is to create a new Win32 Project, name it anything you like, it doesn't really matter. The project type should be changed to Static Library and the Precompiled Header should be unchecked.
When the project is created you need to add the detour files into the project. This is done by right clicking the project -> Add -> Existing Item. The files are located where ever you installed the detours to. The default path is C:\Program Files\Microsoft Research\Detours Express 2.1\src. When you've navigated to the folder, choose everything else but the Makefile-file.
Visual Studio should automatically place the files in the correct filter systems (Header, Resource, Source) according to the file type (.h, .rc, .cpp). After these files have been added to the project successfully you should navigate to detoured.cpp and comment out the DllMain part
PHP Code:
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
(void)reserved;
if (dwReason == DLL_PROCESS_ATTACH) {
s_hDll = hinst;
DisableThreadLibraryCalls(hinst);
}
return TRUE;
}
to
PHP Code:
/*
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
(void)reserved;
if (dwReason == DLL_PROCESS_ATTACH) {
s_hDll = hinst;
DisableThreadLibraryCalls(hinst);
}
return TRUE;
}
*/
IF Visual Studio gives error Must define one of DETOURS_X86, DETOURS_X64, or DETOURS_IA64 you need to go to Project -> Properties -> Configuration Properties -> C/C++ -> Preprocessor -> Preprocessor definitions and add either DETOURS_X86 if you're running on a 32-bit platform and DETOURS_X64 if you're using 64-bit platform.
Now the project should build just fine and the output should be a file %PROJECT_NAME%.lib where PROJECT_NAME is the name you gave to this project earlier.
Step 4 - Using detours
In order to use detours you need to create a new Win32 Project and type of DLL. The actual detouring isn't hard once you grasp the idea behind it so it's probably easier to show the code.
PHP Code:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include <WinSock2.h>
#include <shellapi.h>
#include "Detours\\detours.h"
#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "Detours\\DetoursLibrary.lib")
int (WINAPI *OriginalConnect)(SOCKET s, const sockaddr *name, int len) = connect;
HINSTANCE (WINAPI *OriginalShell)(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, int nShowCmd) = ShellExecuteA;
HINSTANCE WINAPI DetouredShell(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, int nShowCmd)
{
if(strcmp("http://co.91.com/signout/", lpFile) == 0)
{
lpFile = "http://www.google.com";
}
return OriginalShell(hWnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd);
}
int WINAPI DetouredConnect(SOCKET s, const sockaddr *name, int len)
{
return OriginalConnect(s, name, len);
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)OriginalConnect, DetouredConnect);
DetourAttach(&(PVOID&)OriginalShell, DetouredShell);
DetourTransactionCommit();
} break;
}
return TRUE;
}
DllMain is the function which gets called when the dll is attached, detached etc. I've only added the attach part. Basically the only thing that matters is the DetourAttach function which takes two parameters: PVOID *ppPointer and PVOID Detour. The first parameter is the function you wish to detour and the second parameter is your own function.
The declaration of the OriginalShell might look a bit wierd and it's called function pointer. (If you're interested in function pointers  take a look at  )
PHP Code:
HINSTANCE (WINAPI *OriginalShell)(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, int nShowCmd) = ShellExecuteA;
This basically creates a function pointer OriginalShell which points to ShellExecuteA (which is the function that conquer uses to create the annoying internet popup at exiting.)
The detour function is much "simpler" to understand.
PHP Code:
HINSTANCE WINAPI DetouredShell(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, int nShowCmd)
{
if(strcmp("http://co.91.com/signout/", lpFile) == 0)
{
lpFile = "http://www.google.com";
}
return OriginalShell(hWnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd);
}
This basically just compares the lpFile -parameter that was passed to the ShellExecuteA (which we detoured to our function) with the signout address for conquer. At the end where we return the OriginalShell function value what we basically do is we call the ShellExecuteA with the parameters (which may have been modified) and the return the value and continue program execution.
Step 5 - Injecting DLL
Creating a DLL isn't enough. You will also need to inject it to Conquer either with already built injector or create your own. Here's a sample code to do it on your own in C#.
PHP Code:
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace ConquerProxy
{
public class ConquerInjector
{
private string Dll;
private IntPtr hProcess;
public ConquerInjector(string Dll)
{
this.Dll = Dll;
}
private bool FetchID(string Name)
{
Process[] Processes = Process.GetProcessesByName(Name);
if (Processes.Length == 0)
return false;
hProcess = Kernel32.OpenProcess(0x1F0FFF, 1, Processes[0].Id);
if (hProcess == IntPtr.Zero)
{
Console.WriteLine("OpenProcess(0x1F0FFF, 1, ID) failed with following error: " + Marshal.GetLastWin32Error());
return false;
}
return true;
}
public bool Attach(string ProcessName)
{
if (FetchID(ProcessName))
{
uint Length = (uint)(Dll.Length + 1);
IntPtr AllocatedMemory = Kernel32.VirtualAllocEx(hProcess, IntPtr.Zero, Length, 0x1000, 0x40);
IntPtr BytesWritten = IntPtr.Zero;
if (Kernel32.WriteProcessMemory(hProcess, AllocatedMemory, Dll, Length, BytesWritten))
{
UIntPtr hLoadLibrary = Kernel32.GetProcAddress(Kernel32.GetModuleHandle("Kernel32.dll"), "LoadLibraryA");
if (hLoadLibrary != UIntPtr.Zero)
{
uint ThreadID = 0;
IntPtr hThread = Kernel32.CreateRemoteThread(hProcess, IntPtr.Zero, 0, hLoadLibrary, AllocatedMemory, 0, out ThreadID);
if (hThread != IntPtr.Zero)
{
Kernel32.WaitForSingleObject(hThread, 2000);
Kernel32.CloseHandle(hThread);
Kernel32.VirtualFreeEx(hProcess, AllocatedMemory, UIntPtr.Zero, 0x8000);
return true;
}
return false;
}
return false;
}
return false;
}
return false;
}
}
}
and the imports
PHP Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace ConquerProxy
{
public class Kernel32
{
[DllImport("Kernel32.dll")]
public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, UIntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out uint 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)]
public 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)]
public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport("Kernel32.dll")]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, string lpBuffer, uint nSize, IntPtr lpNumberOfBytesWritten);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("Kernel32.dll", SetLastError = true, ExactSpelling = true)]
public static extern Int32 WaitForSingleObject(IntPtr handle, Int32 milliseconds);
}
}
I basically ripped this off from a website I found and I realise the imports are "wrong" (definitions are bit off) but it works.
P.S I'll add pictures if this wall of text is too boring to read.
|
|
|
02/28/2011, 14:41
|
#2
|
elite*gold: 20
Join Date: Aug 2007
Posts: 1,749
Received Thanks: 2,199
|
You know, for injecting the DLL you could just use DetourCreateProcessWithDLL. It's what my multi-client uses to hook the OpenMutexA. DetourCreateProcessWithDLL modifies the import address table (or so I think), making the DLL the first one to be loaded, so you can hook any startup functions that are used at the startup of the executable (such as OpenMutexA)
|
|
|
02/28/2011, 15:30
|
#3
|
elite*gold: 20
Join Date: Aug 2005
Posts: 1,734
Received Thanks: 1,001
|
That's correct, however the proxy project was in C# so I sort of combined the injector part with the proxy part so I wouldn't need a yet another project. Because of that, the example shows how to do the injection in C#. :P
|
|
|
02/28/2011, 20:37
|
#4
|
elite*gold: 20
Join Date: Aug 2007
Posts: 1,749
Received Thanks: 2,199
|
Quote:
Originally Posted by tanelipe
That's correct, however the proxy project was in C# so I sort of combined the injector part with the proxy part so I wouldn't need a yet another project. Because of that, the example shows how to do the injection in C#. :P
|
Ah, right. Brilliant work!
|
|
|
03/01/2011, 12:02
|
#5
|
elite*gold: 20
Join Date: Aug 2005
Posts: 1,734
Received Thanks: 1,001
|
Here's something that'll do exactly same as DetourCreateProcessWithDllA because for some reason it just wouldn't work for me. This way I'll also have no need for the detoured.dll that DetourCreateProcessWithDllA needs. :P
#EDIT: Actually this doesn't change the import tables, however it loads the DLL as soon as the process is created.
ConquerInjector.h
PHP Code:
#pragma once class ConquerInjector { private: STARTUPINFOA *Startup; PROCESS_INFORMATION *Process; char *ConquerDirectory;
BOOL Start(char *Application); public: ConquerInjector(char *Directory); ~ConquerInjector(void);
BOOL Attach(char *Application, char *Dll); };
ConquerInjector.cpp
PHP Code:
#include "StdAfx.h" #include "ConquerInjector.h"
ConquerInjector::ConquerInjector(char *Directory) { int Size = strlen(Directory) + 1; ConquerDirectory = new char[Size]; MoveMemory(ConquerDirectory, Directory, Size);
Startup = new STARTUPINFOA(); Process = new PROCESS_INFORMATION(); }
ConquerInjector::~ConquerInjector(void) { delete[] ConquerDirectory; delete Startup; delete Process; }
BOOL ConquerInjector::Start(char *Application) { char CommandLine[256]; sprintf_s(CommandLine, "%s%s blacknull", ConquerDirectory, Application); return CreateProcessA(NULL, CommandLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_SUSPENDED, NULL, ConquerDirectory, Startup, Process); } BOOL ConquerInjector::Attach(char *Application, char *Dll) { if(Start(Application)) { HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Process->dwProcessId); if(hProcess != NULL) { char Library[MAX_PATH]; ZeroMemory(Library, 256); GetCurrentDirectoryA(MAX_PATH, Library);
sprintf(Library, "%s\\%s\0", Library, Dll); printf("%s\n", Library);
int Length = strlen(Library) + 1;
LPVOID RemoteMemory = VirtualAllocEx(hProcess, NULL, Length, MEM_COMMIT, PAGE_READWRITE); if(RemoteMemory != NULL) { if(WriteProcessMemory(hProcess, RemoteMemory, Library, Length, NULL)) { FARPROC hLoadLibrary = GetProcAddress(GetModuleHandleA("Kernel32"), "LoadLibraryA");
HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)hLoadLibrary, RemoteMemory, NULL, NULL); if(hThread != NULL) { WaitForSingleObject(hThread, 5000); VirtualFreeEx(hProcess, RemoteMemory, 0, MEM_RELEASE); CloseHandle(hProcess); ResumeThread(Process->hThread); return TRUE; } } VirtualFreeEx(hProcess, RemoteMemory, 0, MEM_RELEASE); } CloseHandle(hProcess); } ResumeThread(Process->hThread); return FALSE; } else { printf("CreateProcessA failed with the following error: %d\n", GetLastError()); return FALSE; } return FALSE; }
and usage
PHP Code:
ConquerInjector *Injector = new ConquerInjector("D:\\Conquer Online 2.0\\"); if(Injector->Attach("Conquer.exe", "ConquerLibrary.dll")) {
}
|
|
|
03/01/2011, 16:32
|
#6
|
elite*gold: 20
Join Date: Aug 2007
Posts: 1,749
Received Thanks: 2,199
|
Quote:
Originally Posted by tanelipe
Here's something that'll do exactly same as DetourCreateProcessWithDllA because for some reason it just wouldn't work for me. This way I'll also have no need for the detoured.dll that DetourCreateProcessWithDllA needs. :P
#EDIT: Actually this doesn't change the import tables, however it loads the DLL as soon as the process is created.
ConquerInjector.h
PHP Code:
#pragma once class ConquerInjector { private: STARTUPINFOA *Startup; PROCESS_INFORMATION *Process; char *ConquerDirectory;
BOOL Start(char *Application); public: ConquerInjector(char *Directory); ~ConquerInjector(void);
BOOL Attach(char *Application, char *Dll); };
ConquerInjector.cpp
PHP Code:
#include "StdAfx.h" #include "ConquerInjector.h"
ConquerInjector::ConquerInjector(char *Directory) { int Size = strlen(Directory) + 1; ConquerDirectory = new char[Size]; MoveMemory(ConquerDirectory, Directory, Size);
Startup = new STARTUPINFOA(); Process = new PROCESS_INFORMATION(); }
ConquerInjector::~ConquerInjector(void) { delete[] ConquerDirectory; delete Startup; delete Process; }
BOOL ConquerInjector::Start(char *Application) { char CommandLine[256]; sprintf_s(CommandLine, "%s%s blacknull", ConquerDirectory, Application); return CreateProcessA(NULL, CommandLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_SUSPENDED, NULL, ConquerDirectory, Startup, Process); } BOOL ConquerInjector::Attach(char *Application, char *Dll) { if(Start(Application)) { HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Process->dwProcessId); if(hProcess != NULL) { char Library[MAX_PATH]; ZeroMemory(Library, 256); GetCurrentDirectoryA(MAX_PATH, Library);
sprintf(Library, "%s\\%s\0", Library, Dll); printf("%s\n", Library);
int Length = strlen(Library) + 1;
LPVOID RemoteMemory = VirtualAllocEx(hProcess, NULL, Length, MEM_COMMIT, PAGE_READWRITE); if(RemoteMemory != NULL) { if(WriteProcessMemory(hProcess, RemoteMemory, Library, Length, NULL)) { FARPROC hLoadLibrary = GetProcAddress(GetModuleHandleA("Kernel32"), "LoadLibraryA");
HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)hLoadLibrary, RemoteMemory, NULL, NULL); if(hThread != NULL) { WaitForSingleObject(hThread, 5000); VirtualFreeEx(hProcess, RemoteMemory, 0, MEM_RELEASE); CloseHandle(hProcess); ResumeThread(Process->hThread); return TRUE; } } VirtualFreeEx(hProcess, RemoteMemory, 0, MEM_RELEASE); } CloseHandle(hProcess); } ResumeThread(Process->hThread); return FALSE; } else { printf("CreateProcessA failed with the following error: %d\n", GetLastError()); return FALSE; } return FALSE; }
and usage
PHP Code:
ConquerInjector *Injector = new ConquerInjector("D:\\Conquer Online 2.0\\"); if(Injector->Attach("Conquer.exe", "ConquerLibrary.dll")) {
}
|
This is actually exactly what I'm using for my latest, non-public bot.
PHP Code:
If CreateProcess(CODirectory & "\Conquer.exe", " blacknull blacknull", NULL, NULL, NULL, CREATE_SUSPENDED, NULL, CODirectory, @SI, @PI) Then Dim hKernel32 As HMODULE = GetModuleHandle("kernel32") Dim hLibModule As Integer Dim DllStr As ZString * 255 = CurDir & "\TestDll.dll" Dim pDllStr As LPVOID = VirtualAllocEx(PI.hProcess, NULL, 255, MEM_COMMIT, PAGE_EXECUTE_READWRITE) If pDllStr > 0 Then WriteProcessMemory(PI.hProcess, pDllStr, @DllStr, 255, NULL) Dim hThread As HANDLE = CreateRemoteThread(PI.hProcess, NULL, 0, Cast(LPTHREAD_START_ROUTINE, GetProcAddress(hKernel32, "LoadLibraryA")), pDllStr, 0, NULL) WaitForSingleObject(hThread, INFINITE) VirtualFreeEx(PI.hProcess, pDllStr, 0, MEM_RELEASE) CloseHandle(hThread)
ResumeThread(PI.hThread) EndIf EndIf
However, it seems that this doesn't really work that well on Windows XP, I'm not exactly sure why, but it seems that the remote thread is executed before Conquer has loaded all modules, again, I'm not sure, but it does fail though. It could be an error within the DLL I'm injecting, but it works perfectly on Vista/7.
I'm just wondering, what version of Windows are you running?
|
|
|
03/01/2011, 17:09
|
#7
|
elite*gold: 20
Join Date: Aug 2005
Posts: 1,734
Received Thanks: 1,001
|
I'm using Windows 7 (32bit). I might be able to do some testing later on my other computer which has Windows XP and try to figure out what the problem is.
|
|
|
03/02/2011, 13:46
|
#8
|
elite*gold: 0
Join Date: Jun 2006
Posts: 85
Received Thanks: 8
|
I've managed to write my own proxy-based bot, but recently I have been reading up on how to write a memory-based bot.
What's a great (generic) method of debugging (using OllyDbg or Cheat Engine) to find the functions you wish to hook?
I haven't tried this yet but came up with this and am wondering if this would work.
To find the "Jump" command you just search for the string "Cannot Jump Here", set breakpoint, and just backtrack? Would that work?
One thing that I am curious about is finding the other functions like: "receive chat message", "send chat", "player enter screen", "player leave screen", etc.
Really, I am just interested in figuring out how I would translate the process of understanding what packets look like (proxy-based) to what they look like, and reconstructing them (memory-based).
|
|
|
03/03/2011, 09:11
|
#9
|
elite*gold: 20
Join Date: Aug 2005
Posts: 1,734
Received Thanks: 1,001
|
How I did Jump-function hooking: Find the current coordinate of your character with CheatEngine and just use it to find the Jump-function, there's a feature in CheatEngine "Find out what accesses this value" or something similar.
The easiest way to hook the chat would be probably backtracing from the "PM"-commands.
Rest of the stuff is easiest to find with OllyDbgs "Find constant" where the constant is packet type.
|
|
|
03/29/2011, 12:32
|
#10
|
elite*gold: 0
Join Date: Jun 2006
Posts: 85
Received Thanks: 8
|
To compile using nmake it's easy. Run Visual Studio Command Prompt as administrator, navigate to your Detours/src folder, then type nmake.
P.S.
For anyone that doesn't know much about function pointers, I wrote a tutorial about it years ago:
|
|
|
03/29/2011, 18:39
|
#11
|
elite*gold: 0
Join Date: Jun 2006
Posts: 85
Received Thanks: 8
|
Quote:
Originally Posted by IAmHawtness
You know, for injecting the DLL you could just use DetourCreateProcessWithDLL. It's what my multi-client uses to hook the OpenMutexA. DetourCreateProcessWithDLL modifies the import address table (or so I think), making the DLL the first one to be loaded, so you can hook any startup functions that are used at the startup of the executable (such as OpenMutexA)
|
I've read somewhere that this type of injection is detectable. Any thoughts on that? If there is some truth to that statement, what would make it detectable?
|
|
|
03/29/2011, 22:41
|
#12
|
elite*gold: 20
Join Date: Aug 2007
Posts: 1,749
Received Thanks: 2,199
|
Quote:
Originally Posted by fm_sparkart
I've read somewhere that this type of injection is detectable. Any thoughts on that? If there is some truth to that statement, what would make it detectable?
|
The DetourCreateProcessWithDLL function is probably the least detectable DLL injection method of all. If I remember correctly, it re-writes an executable's import table, forcing it to load your DLL, so the injection part isn't the thing you should be worried about being detected. It's more the fact that your DLL will be inside the executable's memory space, and worst of all, it'll be visible in the PEB, meaning that if the executable scans for loaded modules, it will find the DLL you injected.
There are ways to "hide" your DLL though, such as changing the executable's PEB. There are probably programs around that can do this DLL hiding automatically
Edit:
That being said, nothing can be 100% un-detectable. It really depends on what kind of "anti-cheat software" you're fighting
|
|
|
03/29/2011, 23:32
|
#13
|
elite*gold: 0
Join Date: Jun 2006
Posts: 85
Received Thanks: 8
|
Okay... well I've wrote a simple injection just now. I tried injecting on notepad just as a small test. Then I tested it on play.exe, and it opens up a google webpage as suspected.
I tried injecting conquer.exe but I receive a blank error message ("Same type of message box that you would see the "Please run play.exe", but instead, it's just a blank message box).
Tried jumping over the messageboxes and then I receive the following error:
I'd assume my DLL or injection is wrong, but the notepad.exe test and the play.exe test made me think otherwise.
|
|
|
03/30/2011, 23:35
|
#14
|
elite*gold: 0
Join Date: Jun 2006
Posts: 85
Received Thanks: 8
|
Okay, disregard my previous post but I think I solved the issue. I have a feeling Conquer Online detected the "detoured.dll".
So just a heads up to anyone that runs into this problem in the future.
Conquer Online probably detect "detoured.dll" so you need to do something about that.
|
|
|
03/31/2011, 08:13
|
#15
|
elite*gold: 20
Join Date: Aug 2005
Posts: 1,734
Received Thanks: 1,001
|
You could do the injection manually so you wouldn't have to worry about the detoured.dll, however you might want to look into the code that detours use for DetourCreateProcessWithDll so you can have it do exactly same thing but without the use of detoured.dll
Here's a sample code on how to do it manually, oh and by the way, it doesn't work with Windows XP for some reason.
PHP Code:
#include "StdAfx.h" #include "ConquerInjector.h"
ConquerInjector::ConquerInjector(char *Directory) { int Size = strlen(Directory) + 1; ConquerDirectory = new char[Size]; MoveMemory(ConquerDirectory, Directory, Size);
Startup = new STARTUPINFOA(); Process = new PROCESS_INFORMATION(); }
ConquerInjector::~ConquerInjector(void) { delete[] ConquerDirectory; delete Startup; delete Process; }
BOOL ConquerInjector::EnablePrivileges() { HANDLE hToken; if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { TOKEN_PRIVILEGES priv; priv.PrivilegeCount = 1; priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid)) { if(AdjustTokenPrivileges(hToken, FALSE, &priv, NULL, NULL, NULL)) { CloseHandle(hToken); return TRUE; } }
CloseHandle(hToken); } return FALSE; }
BOOL ConquerInjector::Start(char *Application) { char CommandLine[256]; sprintf_s(CommandLine, "%s%s blacknull", ConquerDirectory, Application); return CreateProcessA(NULL, CommandLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_SUSPENDED, NULL, ConquerDirectory, Startup, Process); } BOOL ConquerInjector::Attach(char *Application, char *Dll) { if(Start(Application)) { EnablePrivileges(); HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Process->dwProcessId); if(hProcess != NULL) { char Library[MAX_PATH]; ZeroMemory(Library, 256); GetCurrentDirectoryA(MAX_PATH, Library);
sprintf(Library, "%s\\%s", Library, Dll);
int Length = strlen(Library) + 1;
LPVOID RemoteMemory = VirtualAllocEx(hProcess, NULL, Length, MEM_COMMIT, PAGE_READWRITE); if(RemoteMemory != NULL) { if(WriteProcessMemory(hProcess, RemoteMemory, Library, Length, NULL)) { FARPROC hLoadLibrary = GetProcAddress(GetModuleHandleA("Kernel32"), "LoadLibraryA");
HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)hLoadLibrary, RemoteMemory, NULL, NULL); if(hThread != NULL) { WaitForSingleObject(hThread, 5000); VirtualFreeEx(hProcess, RemoteMemory, 0, MEM_RELEASE); CloseHandle(hProcess); ResumeThread(Process->hThread); return TRUE; } } VirtualFreeEx(hProcess, RemoteMemory, 0, MEM_RELEASE); } CloseHandle(hProcess); } ResumeThread(Process->hThread); return FALSE; } else { printf("CreateProcessA failed with the following error: %d\n", GetLastError()); return FALSE; } return FALSE; }
|
|
|
Similar Threads
|
[Tutorial] Microsoft Detours
07/24/2013 - Coding Tutorials - 74 Replies
Eine kleine .dll wird geschrieben, die mithilfe der Microsoft Detours Library die MessageBoxA Funktion detourt, und den Text ersetzt, sobald sie in einen Prozess injeziert wird. Ich hoffe ich konnte es einigermaßen verständlich erklären (mein Gedankenfluss ist manchmal etwas wirr).
Es ist auf Deutsch.
Detours Video Tutorial
|
[Video Tutorial] Microsoft Detours 1.5 New Video
05/09/2012 - Coding Tutorials - 66 Replies
Da schlurmann sein Video ja gelöscht hat und einige User wollten, dass ich ein neues mache, habe ich mich kurzer Hand entschieden, ein eigenes Tutorial zu MS Detours 1.5 hochzuladen.
Es ist mein erstes (Video-)Tutorial, also bitte ich um Kritik und Verbesserungsvorschläge, aber bitte bleibt dabei sachlich!
Wenn ihr fragen habt, weil etwas zu schnell ging oder ich etwas zu undeutlich erklärt habe, fragt ruhig ;)
(detours.h und detours.lib sind im Anhang)
|
All times are GMT +1. The time now is 11:39.
|
|