Microsoft Detours 2.1

03/31/2011 11:21 IAmHawtness#16
There's a way to remove the detoured.dll from getting injected into the process. Erm, let me Google it for you, there's a certain include and a function or something you need to remove from the source.

Link:
[Only registered and activated users can see links. Click Here To Register...]

Quote:
Originally Posted by tanelipe View Post
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;
} 
If you change the code
PHP Code:
                    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;
                    } 
Into this (resume main thread before executing the LoadLibrary thread):
PHP Code:
                    ResumeThread(Process->hThread);
                    
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);
                        return 
TRUE;
                    } 
It works on XP. Not that I recommend it though, it would probably be better to hook the import table and manually force the process to load your DLL :p
03/31/2011 12:20 fm_sparkart#17
Yes, I have gotten the issue solved. That's what I meant by do something about it, lol.
03/31/2011 15:14 IAmHawtness#18
Quote:
Originally Posted by fm_sparkart View Post
Yes, I have gotten the issue solved. That's what I meant by do something about it, lol.
Right, I thought you just created your own "CreateProcessWithDLL" function, like the example tanelipe posted, my bad :p.
04/10/2011 12:09 _DreadNought_#19
After I finally got it working & help from Sparkie.

I'm trying to do:
Code:
int WINAPI DetouredConnect(SOCKET s, const sockaddr *name, int len)
{
   sockaddr_in my_addr;
    my_addr.sin_addr.S_un.S_addr = inet_addr("5.94.169.205");
    my_addr.sin_port = htons(5816);
    my_addr.sin_family = AF_INET;
    return OriginalConnect(s, (sockaddr*)&my_addr, sizeof(my_addr));
    //return OriginalConnect(s, name, len);
}
But upon login the client dc's.

#edit
Tried
Code:
struct sockaddr_in dds;
char *some_addr;
dds.sin_addr.s_addr = inet_addr("5.94.169.205");
dds.sin_port = htons(5816);
dds.sin_family = AF_INET;
return OriginalConnect(s, (sockaddr*)&dds, sizeof(dds));
Which is almost the same but it still didn't work. Not a server-side issue not working on other servers either.
04/10/2011 12:36 tanelipe#20
This is how I'm doing my connect-function. It's a bit long because I was saving the IP/Port the client is connecting to.

Biggest difference seems to be with this
PHP Code:
sockaddr_in my_addr; 
VS.
PHP Code:
sockaddr_in *addr = (sockaddr_in*)name; 
PHP Code:
int WINAPI DetouredConnect(SOCKET s, const sockaddr *name, int namelen)
{
    
sockaddr_in *addr = (sockaddr_in*)name;

    
u_short Port = ntohs(addr->sin_port);
    
char szPort[32];

    
sprintf_s(szPort, "%d", Port);

    
char CurrentDirectory[MAX_PATH];
    
GetModuleFileNameA(GetModuleHandleA("ConquerLibrary.dll"),CurrentDirectory,MAX_PATH);
    
int slen = strlen(CurrentDirectory);
    for (
int i =slen -1;i >= 0;i--)
    {
        if (
CurrentDirectory[i] == '\\')
        {
            
CurrentDirectory[i+1] = NULL;
            break;
        }
    }
    
MessageBoxA(NULL, szPort, "", MB_OK);
    if(
Port == 80)
    {
        
strcat_s(CurrentDirectory, "StatusChecker.ini");
    }
    else if(
Port == 5816 || Port == 5817)
    {
        
strcat_s(CurrentDirectory, "GameServer.ini");
        
Port = 5816;
    }
    else
    {
        
strcat_s(CurrentDirectory, "AuthServer.ini");
        
Port = 9958;
    }
    
WritePrivateProfileStringA("Settings", "IP", inet_ntoa(addr->sin_addr), CurrentDirectory);
    
WritePrivateProfileStringA("Settings", "Port", szPort, CurrentDirectory);

    
addr->sin_addr.s_addr = inet_addr("127.0.0.1");
    
addr->sin_port = htons(Port);
    return 
OriginalConnect(s, (const sockaddr*)addr, namelen);
} 
04/10/2011 12:53 _DreadNought_#21
#edit
Got it. Thanks.

*sighs in relief*
02/27/2012 09:35 I don't have a username#22
I know this is kinda an old bump, but better than making a new thread and since it's related to the thread, could anyone possibly upload Detours 2.1? As I can't seems to get Detours 3 working.

Thank you.
02/27/2012 14:43 m7mdxlife#23
Quote:
Originally Posted by I don't have a username View Post
I know this is kinda an old bump, but better than making a new thread and since it's related to the thread, could anyone possibly upload Detours 2.1? As I can't seems to get Detours 3 working.

Thank you.
This one >> [Only registered and activated users can see links. Click Here To Register...] ?
02/27/2012 17:39 I don't have a username#24
Quote:
Originally Posted by m7mdxlife View Post
This one >> [Only registered and activated users can see links. Click Here To Register...] ?
Thanks a lot it was perfect.
02/27/2012 17:46 tkblackbelt#25
Quote:
Originally Posted by m7mdxlife View Post
This one >> [Only registered and activated users can see links. Click Here To Register...] ?
Thanks :). This seems like a fun api to play around with.
02/28/2012 07:37 SpaceUrkel#26
Nice, but couldn't you just configure %systemroot%Drivers\etc\Hosts.txt? I assume that conquer uses somesort of DNS to lookup the server address.
02/28/2012 07:43 I don't have a username#27
Quote:
Originally Posted by SpaceUrkel View Post
Nice, but couldn't you just configure %systemroot%Drivers\etc\Hosts.txt? I assume that conquer uses somesort of DNS to lookup the server address.
Do you even know what this is for?

:facepalm: