You last visited: Today at 23:47
Advertisement
Endscene Detour
Discussion on Endscene Detour within the Hearthstone forum part of the Other Online Games category.
04/03/2014, 16:33
#1
elite*gold: 0
Join Date: Jun 2011
Posts: 96
Received Thanks: 21
Endscene Detour
Hi,
i successfully hooked the directx endscene method in heathstone with easyhook, but when i try to call game functions like GameState.Get().GetLocalPlayer() it throws an exception. Someone knows why its not working? I mean, i am calling the functions from the hooked endscene, which is running in the main thread, so in my opinion it should work fine, but it doesnt....
04/03/2014, 17:58
#2
elite*gold: 240
Join Date: Dec 2006
Posts: 1,579
Received Thanks: 1,609
Would you share your hook ? Maybe we can find the issue. Check whether your really in the main thread.
Also calling GameState.Get() etc. shouldn't be called outside of Unity Engine Tasks, try to call it in a custom MonoBehaviour within Update()
04/03/2014, 19:31
#3
elite*gold: 0
Join Date: Jun 2011
Posts: 96
Received Thanks: 21
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using EasyHook;
using System.Windows.Forms;
using SlimDX;
using SlimDX.Direct3D9;
using System.Diagnostics;
namespace hsBot
{
public class Main : EasyHook.IEntryPoint
{
LocalHook eHook;
public Main(RemoteHooking.IContext InContext, String InChannelName)
{
}
public void Run(RemoteHooking.IContext InContext, String InChannelName)
{
Device dev;
dev = new Device(new Direct3D(), 0, DeviceType.Hardware, IntPtr.Zero, CreateFlags.HardwareVertexProcessing, new PresentParameters() { BackBufferWidth = 1, BackBufferHeight = 1 });
IntPtr address = dev.ComPointer;
address = (IntPtr)Marshal.ReadInt32(address);
address = (IntPtr)((int)address + 0xA8);
address = (IntPtr)Marshal.ReadInt32(address);
eHook = LocalHook.Create((IntPtr)address, new DEndScene(EndSceneHook), this);
eHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
}
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
delegate int DEndScene(IntPtr Direct3dDevice);
public int EndSceneHook(IntPtr Direct3dDevice)
{
using (Device d3d = Device.FromPointer(Direct3dDevice))
{
MessageBox.Show("Called from EndScene");
return d3d.EndScene().Code;
}
}
}
}
This is the code from the injected dll. If i replace the MessageBox with a game function call its throws an exception...
04/03/2014, 21:34
#4
elite*gold: 100
Join Date: Aug 2005
Posts: 595
Received Thanks: 208
You are in the Context of the Nativ Heartstone client, you would need to invoke the function to load an assembly from mono.dll and call the functions from there.
Edit:
Oh and make sure you are calling from the Mainthread, otherwise TLS will bite you
04/03/2014, 22:24
#5
elite*gold: 240
Join Date: Dec 2006
Posts: 1,579
Received Thanks: 1,609
You could hook : mono_exception_from_name_msg and throw an exception for example. Or use any other mono.dll function see dependency walker.
04/04/2014, 20:06
#6
elite*gold: 0
Join Date: Jun 2011
Posts: 96
Received Thanks: 21
Thanks for your answers!
What i am trying now, is to inject a native dll which will load my managed dll with the mono functions, reffering to
:
Code:
#include <windows.h>
#include <cstdio>
#include <mono/jit/jit.h>
#include <mono/metadata/assembly.h>
typedef MonoDomain* (__stdcall * mono_jit_initPointer)(const char* file);
typedef MonoAssembly* (__stdcall * mono_domain_assembly_openPointer)(MonoDomain*, const char* name);
void init()
{
mono_jit_initPointer mono_jit_initRemote;
mono_domain_assembly_openPointer mono_domain_assembly_openRemote;
HINSTANCE hDLL = LoadLibraryA("mono");
mono_jit_initRemote = (mono_jit_initPointer)GetProcAddress(hDLL,"mono_jit_init");
mono_domain_assembly_openRemote = (mono_domain_assembly_openPointer)GetProcAddress(hDLL,"mono_domain_assembly_open");
MonoDomain *domain;
domain= mono_jit_initRemote("Hearthstone");
MonoAssembly *assembly;
assembly = mono_domain_assembly_openRemote(domain, "test.dll");
if (!assembly)
MessageBoxA(NULL,"ERROR", "ERROR", MB_OK);
//int retval = mono_jit_exec (domain, assembly, 0, NULL);
}
int __stdcall DllMain(HINSTANCE hInst,DWORD reason,LPVOID reserved)
{
switch(reason)
{
case DLL_PROCESS_ATTACH:
init();
break;
}
return true;
}
If i inject that code, Hearthstone just closes.
I am not sure what the domain_name is for use in mono_jit_init (domain_name)?
I tried to detour that function and grab the domain_name parameter, but i am not able to inject the dll before the first mono_jit_init call is made...
Some suggestions?
04/04/2014, 22:18
#7
elite*gold: 100
Join Date: Aug 2005
Posts: 595
Received Thanks: 208
Look for process creation, suspend it, add your hook, resume.
EDIT: Fetch the right domain name from the initialization of the monovm for the heartstone logic code.
Guess you can read it from memory, but hooking it seems like a legit solution.
Another approach, hook the assembly loading and manipulate the bytecode onthefly to load your dll.
04/04/2014, 23:29
#8
elite*gold: 0
Join Date: Jun 2011
Posts: 96
Received Thanks: 21
Code:
MonoDomain *domain = mono_domain_get();
MonoAssembly *monoAssembly = mono_domain_assembly_open(domain, "D:\\loadDll.dll");
MonoImage *image = mono_assembly_get_image (monoAssembly);
MonoClass *my_class = mono_class_from_name (image, "MyNamespace", "Loader");
MonoObject* obj = mono_object_new (domain, my_class);
MonoMethod *method = NULL, *m = NULL;
void* iter;
iter = NULL;
while ((m = mono_class_get_methods (my_class, &iter))) {
if (strcmp (mono_method_get_name (m), "testMethod") == 0) {
method = m;
}
}
void *args[1];
args[0] = mono_string_new(mono_domain_get(), "blup");
mono_runtime_invoke(method, obj, args, NULL);
Someone got an idead why mono_runtime_invoke is not working(no error, but the method does not get called)?
04/06/2014, 11:19
#9
elite*gold: 240
Join Date: Dec 2006
Posts: 1,579
Received Thanks: 1,609
Did you find a solution ? I am interested in this.
04/06/2014, 12:20
#10
elite*gold: 0
Join Date: Jun 2011
Posts: 96
Received Thanks: 21
Still having trouble with invoking the method...
The above codes loads the assembly, gets the image, gets the class and finally gets the the right method. All these steps are working, but executing the method does not and i have no clue why its not working...
04/06/2014, 13:36
#11
elite*gold: 240
Join Date: Dec 2006
Posts: 1,579
Received Thanks: 1,609
Would you zip your solution? I can help you better then. Invoking your plugin method shouldn't be that hard.
04/06/2014, 15:52
#12
elite*gold: 0
Join Date: Jun 2011
Posts: 96
Received Thanks: 21
Code:
#include <Windows.h>
#include "Detours\detours.h"
#include <mono/jit/jit.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/debug-helpers.h>
#pragma comment(lib,"mono/mono.lib")
#include <d3dx9.h>
#include <d3d9.h>
bool loaded = false;
typedef HRESULT(__stdcall* EndScene_t)(LPDIRECT3DDEVICE9);
EndScene_t pEndScene;
HRESULT __stdcall hkEndScene(LPDIRECT3DDEVICE9 pDevice)
{
if(!loaded)
{
loaded = true;
MessageBoxA(NULL,"Loading stuff from EndScene", "asd", MB_OK);
MonoDomain *domain = mono_domain_get();
MonoAssembly *monoAssembly = mono_domain_assembly_open(domain, "D:\\loadDll.dll");
MonoImage *image = mono_assembly_get_image (monoAssembly);
MonoClass *my_class = mono_class_from_name (image, "MyNamespace", "Loader");
MonoObject* obj = mono_object_new (domain, my_class);
MonoMethod *method = NULL, *m = NULL;
void* iter;
iter = NULL;
while ((m = mono_class_get_methods (my_class, &iter))) {
if (strcmp (mono_method_get_name (m), "testMethod") == 0) {
method = m;
}
}
//void *args[1];
//args[0] = mono_string_new(mono_domain_get(), "D:\\loadDll.dll");
MessageBoxA(NULL,"executing","",MB_OK);
mono_runtime_invoke(method, NULL, NULL, NULL);
MessageBoxA(NULL,"executed","",MB_OK);
}
return pEndScene(pDevice);
}
bool bCompare(const BYTE* pData, const BYTE* bMask, const char* szMask)
{
for(;*szMask;++szMask,++pData,++bMask)
if(*szMask=='x' && *pData!=*bMask )
return false;
return (*szMask) == NULL;
}
DWORD FindPattern(DWORD dwAddress,DWORD dwLen,BYTE *bMask,char * szMask)
{
for(DWORD i=0; i < dwLen; i++)
if( bCompare( (BYTE*)( dwAddress+i ),bMask,szMask) )
return (DWORD)(dwAddress+i);
return 0;
}
void init()
{
DWORD* vtbl = 0;
DWORD table = FindPattern((DWORD)GetModuleHandleA("d3d9.dll"), 0x128000, (PBYTE)"\xC7\x06\x00\x00\x00\x00\x89\x86\x00\x00\x00\x00\x89\x86", "xx????xx????xx");
memcpy(&vtbl, (void*)(table+2), 4);
DWORD EndSceneaddy = vtbl[42];
pEndScene = ( EndScene_t )DetourFunction((PBYTE) EndSceneaddy,(PBYTE)hkEndScene);
}
int __stdcall DllMain(HINSTANCE hInst,DWORD reason,LPVOID reserved)
{
switch(reason)
{
case DLL_PROCESS_ATTACH:
init();
break;
}
return true;
}
Okay this is the code for the dll you have to inject.
First you need to include Microsoft Detours which i put in the attachment.
You need to get the DirectX Sdk from here:
and include the source and libs in your projects.
These steps are necessary for the EndScene Hook. We need that Hook, because we need to load the assemblys from the MainThread of Hearthstone.
Also you need to get the mono source files from:
and include them in your project.
The last step is to include the mono.lib which i put in the attachment.
Now you should be able to compile the dll and inject it.
The net dll which should be loaded and executed looks like this:
Code:
using System;
using System.Collections.Generic;
using System.Text;
namespace MyNamespace
{
public class Loader
{
public Loader()
{
System.Windows.Forms.MessageBox.Show("aus dll");
}
public static void testMethod()
{
System.Windows.Forms.MessageBox.Show("aus testMethod");
}
}
Attached Files
mono.lib.zip
(33.1 KB, 10 views)
Detours.rar
(52.8 KB, 13 views)
04/06/2014, 19:22
#13
elite*gold: 240
Join Date: Dec 2006
Posts: 1,579
Received Thanks: 1,609
ok, trying it out - i am familar with detours so let me try something
04/06/2014, 20:11
#14
elite*gold: 0
Join Date: Jun 2011
Posts: 96
Received Thanks: 21
If you need some other detours for the mono functions
Code:
typedef MonoDomain* (__cdecl * mono_jit_init_versionPointer)(const char* file, const char* version);
typedef MonoAssembly* (__cdecl * mono_domain_assembly_openPointer)(MonoDomain* domain, const char* name);
typedef MonoAssembly* (__cdecl * mono_assembly_loadPointer) (MonoAssemblyName *aname, const char *basedir, MonoImageOpenStatus *status);
typedef int (__cdecl * mono_jit_execPointer)(MonoDomain* domain, MonoAssembly* assembly, int argc, char** argv);
typedef MonoClass* (__cdecl * mono_class_from_namePointer)(MonoImage* image, const char* name_space, const char* name);
typedef MonoObject* (__cdecl * mono_object_newPointer)(MonoDomain* domain, MonoClass* klass);
typedef void (__cdecl * mono_runtime_object_initPointer)(MonoObject* thisObject);
typedef MonoMethod* (__cdecl * mono_method_desc_search_in_classPointer)(MonoMethodDesc *desc, MonoClass *klass);
typedef MonoObject* (__cdecl * mono_runtime_invokePointer)(MonoMethod *method, void *obj, void **params, MonoObject **exc);
mono_jit_init_versionPointer pInit;
mono_assembly_loadPointer pAssemblyLoad;
mono_jit_execPointer pMono_jit_exec;
mono_class_from_namePointer pMono_class_from_name;
mono_object_newPointer pMono_object_new;
mono_domain_assembly_openPointer pMono_domain_assembly_open;
mono_runtime_object_initPointer pMono_runtime_object_init;
mono_method_desc_search_in_classPointer pMono_method_desc_search_in_class;
mono_runtime_invokePointer pMono_runtime_invoke;
MonoObject* __cdecl hkmono_runtime_invoke(MonoMethod *method, void *obj, void **params, MonoObject **exc)
{
MessageBoxA(NULL,"a","a",MB_OK);
return pMono_runtime_invoke(method,obj,params,exc);
}
MonoMethod* __cdecl hkmono_method_desc_search_in_class(MonoMethodDesc *desc, MonoClass *klass)
{
MessageBoxA(NULL,"a","a",MB_OK);
return pMono_method_desc_search_in_class(desc, klass);
}
void __cdecl hkmono_runtime_object_init(MonoObject* thisObject)
{
MessageBoxA(NULL,"a","a",MB_OK);
pMono_runtime_object_init(thisObject);
}
MonoAssembly* __cdecl hkmono_domain_assembly_open(MonoDomain* domain, const char* name)
{
MessageBoxA(NULL,name,name,MB_OK);
return pMono_domain_assembly_open(domain, name);
}
MonoObject* __cdecl hkmono_object_new(MonoDomain* domain, MonoClass* klass)
{
MessageBoxA(NULL,"a","a",MB_OK);
return pMono_object_new(domain, klass);
}
MonoClass* __cdecl hkmono_class_from_name(MonoImage* image, const char* name_space, const char* name)
{
MessageBoxA(NULL,name_space,name,MB_OK);
return pMono_class_from_name(image, name_space, name);
}
int __cdecl hkmono_jit_execPointer(MonoDomain* domain, MonoAssembly* assembly, int argc, char** argv)
{
MessageBoxA(NULL,"a","A",MB_OK);
return pMono_jit_exec(domain,assembly,argc,argv);
}
MonoAssembly* __cdecl hkAssemblyLoad(MonoAssemblyName *aname, const char *basedir, MonoImageOpenStatus *status)
{
return pAssemblyLoad(aname,basedir,status);
}
MonoDomain* __cdecl hkInit(const char* file, const char* version)
{
MessageBoxA(NULL,file,file,MB_OK);
return pInit(file, version);
}
HINSTANCE hDLL = GetModuleHandleA("mono.dll");
pInit = ( mono_jit_init_versionPointer )DetourFunction((PBYTE) GetProcAddress(hDLL,"mono_jit_init_version"),(PBYTE)hkInit);
pAssemblyLoad = ( mono_assembly_loadPointer )DetourFunction((PBYTE) GetProcAddress(hDLL,"mono_assembly_load"),(PBYTE)hkAssemblyLoad);
pMono_jit_exec = ( mono_jit_execPointer )DetourFunction((PBYTE) GetProcAddress(hDLL,"mono_jit_exec"),(PBYTE)hkmono_jit_execPointer);
pMono_class_from_name = (mono_class_from_namePointer)DetourFunction((PBYTE) GetProcAddress(hDLL,"mono_class_from_name"),(PBYTE)hkmono_class_from_name);
//pMono_object_new = (mono_object_newPointer)DetourFunction((PBYTE) GetProcAddress(hDLL,"mono_object_new"),(PBYTE)hkmono_object_new);
pMono_domain_assembly_open = (mono_domain_assembly_openPointer)DetourFunction((PBYTE) GetProcAddress(hDLL,"mono_domain_assembly_open"),(PBYTE)hkmono_domain_assembly_open);
pMono_runtime_object_init = (mono_runtime_object_initPointer)DetourFunction((PBYTE) GetProcAddress(hDLL,"mono_runtime_object_init"),(PBYTE)hkmono_runtime_object_init);
//pMono_method_desc_search_in_class = (mono_method_desc_search_in_classPointer)DetourFunction((PBYTE) GetProcAddress(hDLL,"mono_method_desc_search_in_class"),(PBYTE)hkmono_method_desc_search_in_class);
pMono_runtime_invoke = (mono_runtime_invokePointer)DetourFunction((PBYTE) GetProcAddress(hDLL,"mono_runtime_invoke"),(PBYTE)hkmono_runtime_invoke);
04/06/2014, 22:23
#15
elite*gold: 240
Join Date: Dec 2006
Posts: 1,579
Received Thanks: 1,609
I got the EndScene Hook running now. Trying mono now
Similar Threads
Detour und Rehook?! oder nur Detour?
09/16/2011 - WarRock - 4 Replies
Hallo EPVP'
Ich hätte mal ne kleine Frage an die D3D Coder C++.
Ich hab schon meinen eigenen Hack gecoded.
Nun woltle ich D3D Funcs adden, hab auch den richtigen code. In-Game geht es jedoch NICHT!.
Nun wurde mir von jemanden gesagt ich bräuchte eine Detour.
[C++]EndScene hook
01/04/2011 - C/C++ - 7 Replies
Hallo Community,
ich habe ein Problem mit dem Thema 'EndScene' hooking.
Ich habe eine DLL geschrieben (Source unten).
Wenn ich diese in z.b. Css injecte um zu gucken ob bis jetzt alles richtig ist,
sprich ob das game crasht oder nicht.
Jedoch sagt Winject beim injecten der DLL "Both injection methods failed, target is protectet?".
Wenn ich jedoch eine DLL injecte, die einfach nur ne MSGBOX ausgibt, klappt es wunderbar.
Nun ist meine Frage, liegt der Fehler im Source meiner DLL oder ist...
d3d9.dll endscene
10/09/2010 - General Coding - 38 Replies
Huhu,
In meiner d3d9.dll scheint es keine endscene zu geben, ich habe mit IDA unter Functions den String "endscene" gesucht und er sagt mir jedes mal "string not found...".
Ich hab mir jetzt auch schon eine aus'm Jahr 2002 geladen und IDA findet da komischer weiße auch nichts.
Hat wer vllt nen lösungs vorschlag?
d3d9.dll EndScene ?
07/19/2010 - General Coding - 7 Replies
Hey, ich wollte mal fragen ob es noch möglich ist die Funktion EndScene aus der d3d9.dll zu hooken. Weil bei mir findet IDA die Funktion EndSene nicht...
Ich hab Windows 7 64 bit Professional. (In der d3d10.dll ist auch keine Funktion die EndSene heißt)
mfG
All times are GMT +1. The time now is 23:48 .