Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Trouble with injecting C++ speedhack.dll

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
BullyWiiPlaza
How do I cheat?
Reputation: 0

Joined: 28 May 2018
Posts: 8

PostPosted: Fri Jun 22, 2018 3:12 am    Post subject: Trouble with injecting C++ speedhack.dll Reply with quote

I set up a C++ project for a Cheat Engine like speed hack and for DLL injection. My problem is that after injection, the speedhack.dll is instantly unloaded again. First of all, here is the source code for the speed hack.

speed_hack.cpp:
Code:
#include "stdafx.h"
#include <windows.h>
#include "detours.h"
#include <cstdint>

// Function pointers
DWORD (WINAPI *d_get_tick_count)() = GetTickCount;
DWORD (WINAPI *dtime_get_time)() = timeGetTime;
BOOL (WINAPI *d_query_performance_counter)(LARGE_INTEGER* lp_performance_count) = QueryPerformanceCounter;

// Global variables remembering the base values
DWORD base_tick_count;
DWORD base_get_time;
int64_t base_performance_count;

// The speedup
DWORD acceleration = 4;

DWORD WINAPI get_tick_count_hook()
{
   const auto current_tick_count = d_get_tick_count();
   return base_tick_count + (current_tick_count - base_tick_count) * acceleration;
}

DWORD WINAPI time_get_time_hook()
{
   const auto current_get_time = dtime_get_time();
   return base_get_time + (current_get_time - base_get_time) * acceleration;
}

BOOL WINAPI query_performance_counter_hook(LARGE_INTEGER* lp_performance_count)
{
   int64_t current_performance_count;
   if (!d_query_performance_counter(reinterpret_cast<LARGE_INTEGER*>(&current_performance_count)))
   {
      return FALSE;
   }
   auto new_time = current_performance_count + (current_performance_count - base_performance_count) * acceleration;
   *lp_performance_count = *reinterpret_cast<LARGE_INTEGER*>(&new_time);
   return TRUE;
}

DWORD WINAPI initialize_hooks(LPVOID lp_param)
{
   base_tick_count = GetTickCount();
   base_get_time = timeGetTime();
   QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&base_performance_count));
   DetourTransactionBegin();
   DetourUpdateThread(GetCurrentThread());
   DetourAttach(&reinterpret_cast<PVOID&>(d_get_tick_count), get_tick_count_hook);
   DetourAttach(&reinterpret_cast<PVOID&>(dtime_get_time), time_get_time_hook);
   DetourAttach(&reinterpret_cast<PVOID&>(d_query_performance_counter), query_performance_counter_hook);
   DetourTransactionCommit();

   return EXIT_SUCCESS;
}

// ReSharper disable once CppInconsistentNaming
// ReSharper disable once CppParameterMayBeConst
INT APIENTRY DllMain(HMODULE h_dll_handle, DWORD n_reason, LPVOID reserved)
{
   HANDLE h_thread = nullptr;
   switch (n_reason)
   {
      case DLL_PROCESS_ATTACH:
         h_thread = CreateThread(nullptr, 0, initialize_hooks, nullptr, 0, nullptr);
         break;

      case DLL_PROCESS_DETACH:
         break;

      default:
         break;
   }

   if (h_thread != nullptr)
   {
      return TRUE;
   }

   return FALSE;
}

As DLL injector I'm using this project (with minor fixes such as adding Windows 10 detection):
GitHub OpenSecurityResearch/dllinjector
My command line parameters for the injector are as follows:
Code:
-p 12264 -l "D:\Cpp\SpeedHack\Debug\SpeedHack.dll" -P -c

This means the following:
* Specify the PID of the target process
* Specify the DLL to be injected
* Allocate memory for just the file path (implies LoadLibrary)
* Use CreateRemoteThread()

On execution of CreateRemoteThread(), the DLL is loaded into the target process but then again unloaded when CreateRemoteThread() returns and before the injector process terminated.

How can I fix this problem? Do you see anything wrong? Cheat Engine is able to successfully speed hack the same process so it is definitely possible. I don't know Pascal programming so please assist me with the C++. Razz
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 198

Joined: 25 Jan 2006
Posts: 8516
Location: 127.0.0.1

PostPosted: Fri Jun 22, 2018 2:21 pm    Post subject: Reply with quote

Add error reporting via something like OutputDebugString and check the returns of things.

You should not be doing your detouring inside of a new thread like that either. GetCurrentThread is going to return your thread, not the intended thread you want.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
OldCheatEngineUser
Whateven rank
Reputation: 20

Joined: 01 Feb 2016
Posts: 1586

PostPosted: Fri Jun 22, 2018 10:17 pm    Post subject: Reply with quote

not really sure:
you might want to, GetWindowThreadProcessId to get process main thread.

_________________
About Me;
I Use CE Since Version 1.X, And Still Learning How To Use It Well!
Jul 26, 2020
STN wrote:
i am a sweetheart.
Back to top
View user's profile Send private message Visit poster's website
BullyWiiPlaza
How do I cheat?
Reputation: 0

Joined: 28 May 2018
Posts: 8

PostPosted: Sat Jun 23, 2018 5:10 pm    Post subject: Reply with quote

Well, atom0s' suggestions don't work. The DLL always gets unloaded though and OutputDebugString() isn't printed anywhere. Am I supposed to see the prints in the debugger's log (e.g. x64dbg)? Nothing is added there (but it would be nice if it worked like that).

I realized the DLL was 32-bit and the game process is 64-bit but I can't seem to get detour 64-bit binaries so I may be stuck there: stackoverflow. com/questions/51004020

The DLL unloading seems to be expected behavior since DllMain() exits:
msdn.microsoft. com/en-us/library/windows/desktop/ms684175%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
But how else would you write the DLL to apply the hooks?

Doesn't anyone have a working C++ injector.exe and speedhack.dll for 64-bit and Windows 10 with full sources or even without sources which just painlessly work? I easily spent 1 full day on doing this but no success. I can't believe this hasn't been done since it's a rather common need how it seems.
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 198

Joined: 25 Jan 2006
Posts: 8516
Location: 127.0.0.1

PostPosted: Sat Jun 23, 2018 8:49 pm    Post subject: Reply with quote

You can use a tool like DbgView to see OutputDebugString output:
https://docs.microsoft.com/en-us/sysinternals/downloads/debugview

Make sure no other tool is running that may swallow the output though.

As for the DLL unloading, it will only immediately unload if you return FALSE from the DllMain function. If you are returning true, it will remain loaded as long as all valid conditions are met.

You must ensure the DLL has all required dependencies available to it where it's loaded from (such as additional referenced imports etc.) and that the runtime its compiled against is installed on the machine.

If you are compiling in debug mode and using that dll on another machine, it wont load either as you wont have the debug runtime on the other machine most likely. Make sure you are compiling in release mode with proper configuration settings etc.

Outside of that, if you still can't get OutputDebugString to work, create a logging function to write to a file and output information of the returns or use MessageBox instead. Either way, you need to check your returns and do some self-debugging to see whats failing.

You can debug the DLL as well if you attach Visual Studio to the target process first, set breakpoints in your DLL's project code, and then inject it as well (as long as its compiled in debug mode and symbols are available properly).

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
BullyWiiPlaza
How do I cheat?
Reputation: 0

Joined: 28 May 2018
Posts: 8

PostPosted: Tue Jul 10, 2018 9:27 am    Post subject: Reply with quote

Overall I started a new project for the speed hack using PolyHook (github. com/stevemk14ebr/PolyHook) since detours didn't support 64-bit. Still, I'm having the same problem of an unloading DLL. I'm looking for efficient ways to debug my DLL now.

atom0s wrote:
You can debug the DLL as well if you attach Visual Studio to the target process first, set breakpoints in your DLL's project code, and then inject it as well (as long as its compiled in debug mode and symbols are available properly).

I tried this, but Visual Studio kept saying:
"The breakpoint will not currently be hit. No symbols have been loaded for this document."
fs5.directupload.net/images/180710/ayqjukd4.png

I followed the tutorial "Debugging an Injected DLL" from UnKnoWnCheaTs.

I injected the DLL using a command line injector and it didn't hit the breakpoint in Visual Studio (it was set at the top of DllMain of course).

x86_dbg said the following while injecting:
Code:
Thread 2B60 created, Entry: <kernel32.LoadLibraryA>
DLL Loaded: 00007FF9B9F60000 D:\Cpp\x64-Speed-Hack\x64\Debug\x64-Speed-Hack.dll
DLL Loaded: 00007FF9C84D0000 C:\Windows\System32\ucrtbased.dll
DLL Loaded: 00007FF9C52C0000 C:\Windows\System32\msvcp140d.dll
DLL Loaded: 00007FFA0E000000 C:\Windows\System32\dbghelp.dll
DLL Loaded: 00007FF9F5C70000 C:\Windows\System32\vcruntime140d.dll
DLL Loaded: 0000000000900000 C:\Windows\System32\vcruntime140d.dll
DLL Unloaded: 0000000000900000 vcruntime140d.dll
DLL Unloaded: 00007FF9C52C0000 msvcp140d.dll
DLL Unloaded: 00007FFA0E000000 dbghelp.dll
DLL Unloaded: 00007FF9F5C70000 vcruntime140d.dll
DLL Unloaded: 00007FF9C84D0000 ucrtbased.dll
DLL Unloaded: 00007FF9B9F60000 x64-speed-hack.dll
Thread 2B60 exit

DbgView shows a lot of random stuff since it seems to work for all processes but none of my messages appeared. Maybe the DLL isn't even executed at all? Rolling Eyes
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 198

Joined: 25 Jan 2006
Posts: 8516
Location: 127.0.0.1

PostPosted: Tue Jul 10, 2018 10:29 pm    Post subject: Reply with quote

Quote:
Overall I started a new project for the speed hack using PolyHook (github. com/stevemk14ebr/PolyHook) since detours didn't support 64-bit. Still, I'm having the same problem of an unloading DLL. I'm looking for efficient ways to debug my DLL now.


If you get the latest Detours v3, they did include x64 support now for free. (Assuming you are referring to Microsoft Detours.)

Quote:
I tried this, but Visual Studio kept saying:
"The breakpoint will not currently be hit. No symbols have been loaded for this document."


You'll get that message/warning if one of the following things happens:
- Your DLL is not currently loaded in the process.
- Your DLL has been rebuilt since attaching to the debugger.
- Your DLL symbols have been overwritten since attaching the debugger.

Generally, its the first one, your DLL is probably not loaded. As based on the x86_dbg output, it looks like your DLL is unloaded immediately. This is usually due to one of the following:
- You are returning FALSE in your DllMain instead of TRUE.
- You are causing an unhandled exception within the entry point.
- You are causing a loader-lock timeout to happen due to your DLL taking too long to load/return from its entry point.
- You are doing something else that is missing information/dependencies that are required for your DLL to load properly but it cannot find them. (Such as imports or other referenced assemblies.)

Quote:
DbgView shows a lot of random stuff since it seems to work for all processes but none of my messages appeared. Maybe the DLL isn't even executed at all? Rolling Eyes


You can use the filtering to prevent seeing other info you don't need. You can also use DbgView++ which has a much better filter system.
https://github.com/CobaltFusion/DebugViewPP[/code]

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
BullyWiiPlaza
How do I cheat?
Reputation: 0

Joined: 28 May 2018
Posts: 8

PostPosted: Thu Jul 12, 2018 10:35 am    Post subject: Reply with quote

But compiling detours (github. com/Microsoft/Detours) does not create any 64-bit binaries and this is the latest version released.

I guess my DLL crashes and doesn't even execute but how I debug this problem if Visual Studio doesn't hit breakpoints?

I successfully compiled and linked my DLL so why could there still be dependency errors then?

I tried Dependency Walker and got a few errors.

Here is the DWI file which you can load and inspect yourself:
mega.nz/#!e48DgL5C!zGLEisxfSc6ftOS7A7WBig7SJv0td6vp1dgykSvWK_s

How do I go about fixing the errors? Do you see anything particularly wrong?

Alternatively, here's also the dumpbin output:

Code:
dumpbin /dependents "D:\Cpp\x64-Speed-Hack\x64\Debug\x64-Speed-Hack.dll"
Microsoft (R) COFF/PE Dumper Version 14.14.26431.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file D:\Cpp\x64-Speed-Hack\x64\Debug\x64-Speed-Hack.dll

File Type: DLL

  Image has the following dependencies:

    WINMM.dll
    KERNEL32.dll
    MSVCP140D.dll
    dbghelp.dll
    VCRUNTIME140D.dll
    ucrtbased.dll

  Summary

        1000 .00cfg
      169000 .data
        2000 .idata
        8000 .pdata
       C2000 .rdata
        A000 .reloc
        1000 .rsrc
      19A000 .text
       C9000 .textbss
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 198

Joined: 25 Jan 2006
Posts: 8516
Location: 127.0.0.1

PostPosted: Thu Jul 12, 2018 4:46 pm    Post subject: Reply with quote

Quote:
But compiling detours (github. com/Microsoft/Detours) does not create any 64-bit binaries and this is the latest version released.


You have to compile it for 64bit mode properly. Not just download and compile without setting things up. Projects can have different build modes that you have to manually pick, otherwise, it'll default to a specific one in the makefiles and only create that one. The latest version is 4.0.1 which can be found on Github now:
https://github.com/Microsoft/Detours

As a means to just double check things, one setting that can often cause injections to fail in a DLL is 'Debug Information Format'. For example, Detours from Microsoft often fails to work if this is set incorrectly.

Try adjusting that via:
- Right-click your project in Visual Studio's solution explorer.
- Choose 'Properties' at the bottom.
- Click on the 'Configuration Properties' in the list on the left to expand it.
- Click on the 'C/C++' settings on the list to the left to expand it.
- Click on 'General' to view the general properties.
- Find the 'Debug Information Format' entry and change it to: 'Program Database (/Zi)'

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
BullyWiiPlaza
How do I cheat?
Reputation: 0

Joined: 28 May 2018
Posts: 8

PostPosted: Fri Jul 13, 2018 6:17 am    Post subject: Reply with quote

Thank you! Finally, I got the DLL injection working.

I figured out how to compile detours for 64-bit:
stackoverflow. com/a/51324338/3764804

Then I rebuilt my SpeedHack.dll as 64-bit DLL and injected it. The speed hack took effect as expected. Nice Smile

However, I still didn't manage to get Visual Studio to break on my code even though the DLL was injected successfully. Your 3 tips didn't seem to help but I really need debugging capabilities as well. The debug messages showed up in DebugView++ though, all good, nothing fails.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites