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 


How to convert my CreateProcessW hook to CreateProcessA hook

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
rain-13
Expert Cheater
Reputation: 0

Joined: 18 Mar 2009
Posts: 110

PostPosted: Mon Jul 13, 2015 2:41 pm    Post subject: How to convert my CreateProcessW hook to CreateProcessA hook Reply with quote

Hi

How do I correctly convert CreateProcessW hook to CreateProcessA hook? The thing is that here in documentation https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx it says LPCTSTR actually compiler automatically sees LPCTSTR as LPCWSTR.

What shall I exactly change in my code? Sorry for this dumb question. I am still new to C/C++.

full code:
Code:
#include <Windows.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include "MinHook.h"

#if defined _M_X64
#pragma comment(lib, "libMinHook.x64.lib")
#elif defined _M_IX86
#pragma comment(lib, "libMinHook.x86.lib")
#endif

// Helper function for MH_CreateHookApi().
template <typename T>
inline MH_STATUS MH_CreateHookApiEx(LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, T** ppOriginal)
{
    return MH_CreateHookApi(pszModule, pszProcName, pDetour, reinterpret_cast<LPVOID*>(ppOriginal));
}

typedef HANDLE (WINAPI *CREATEFILEW)(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
typedef BOOL (WINAPI *CREATEPROCESSW)(LPCTSTR, LPTSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCTSTR, LPSTARTUPINFO, LPPROCESS_INFORMATION);

// Pointer for calling original MessageBoxW.
CREATEFILEW fpCreteFileW= NULL;
CREATEPROCESSW fpCreateProcessW= NULL;

void createConsole(){
   int hCrt = 0;
   FILE* hf_out = NULL;
   HANDLE handle_in = NULL;
   FILE* hf_in = NULL;
   HANDLE handle_out = NULL;

   AllocConsole();
   handle_out = GetStdHandle(STD_OUTPUT_HANDLE);
   hCrt = _open_osfhandle((long) handle_out, _O_TEXT);
   hf_out = _fdopen(hCrt, "w");
   setvbuf(hf_out, NULL, _IONBF, 1);
   *stdout = *hf_out;
 
   handle_in = GetStdHandle(STD_INPUT_HANDLE);
   hCrt = _open_osfhandle((long) handle_in, _O_TEXT);
   hf_in = _fdopen(hCrt, "r");
   setvbuf(hf_in, NULL, _IONBF, 128);
   *stdin = *hf_in;
}

// Detour function which overrides MessageBoxW.
HANDLE WINAPI DetourCreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess,DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
   if(lpFileName != NULL){
      wprintf(L"File: %s %x %x\n",lpFileName, dwDesiredAccess, dwShareMode);
      if(wcscmp(lpFileName,L"C:\\Windows\\System32\\drivers\\etc\\hosts") == 0 && //Deny access to this one specific file
      dwDesiredAccess == 0xC0000000){
         return INVALID_HANDLE_VALUE;
      }
   }
    return fpCreteFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);

}

template<typename TypeA>
TypeA getStr(TypeA x){
   if(x == NULL){
      return L"NULL";
   }
   return x;
}

template<typename TypeB>
TypeB getInt(TypeB x){
   if(x == NULL){
      return 0;
   }
   return x;
}


// Detour function which overrides MessageBoxW.
BOOL WINAPI DetourCreateProcessW(
  _In_opt_    LPCTSTR               lpApplicationName,
  _Inout_opt_ LPTSTR                lpCommandLine,
  _In_opt_    LPSECURITY_ATTRIBUTES lpProcessAttributes,
  _In_opt_    LPSECURITY_ATTRIBUTES lpThreadAttributes,
  _In_        BOOL                  bInheritHandles,
  _In_        DWORD                 dwCreationFlags,
  _In_opt_    LPVOID                lpEnvironment,
  _In_opt_    LPCTSTR               lpCurrentDirectory,
  _In_        LPSTARTUPINFO         lpStartupInfo,
  _Out_       LPPROCESS_INFORMATION lpProcessInformation
   )
{
   wprintf(L"sdfsdfds");
   if(&lpApplicationName != NULL){
      wprintf(L"Process: '%s' '%s' %X %X %d %X %X '%s' %X %X\n",getStr(lpApplicationName), getStr(lpCommandLine), getInt(lpProcessAttributes), getInt(lpThreadAttributes),
         getInt(bInheritHandles), getInt(dwCreationFlags), getInt(lpEnvironment), getStr(lpCurrentDirectory), getInt(lpStartupInfo), getInt(lpProcessInformation));
   }
    return fpCreateProcessW(lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,dwCreationFlags,lpEnvironment,lpCurrentDirectory,lpStartupInfo,lpProcessInformation);

}


INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved)
{
    switch(Reason)
    {
    case DLL_PROCESS_ATTACH:
      createConsole();
      MessageBox(0,L"",L"Hooked",0);
      // Initialize MinHook.
      if (MH_Initialize() != MH_OK)
      {
         return 1;
      }

      // Create a hook for MessageBoxW, in disabled state.
      if (MH_CreateHookApiEx(L"Kernel32", "CreateFileW", &DetourCreateFileW, &fpCreteFileW) != MH_OK)
      {
         return 1;
      }

      // Enable the hook for MessageBoxW.
      if (MH_EnableHook(&CreateFileW) != MH_OK)
      {
         return 1;
      }

      //process
      // Create a hook for MessageBoxW, in disabled state.
      if (MH_CreateHookApiEx(L"Kernel32", "CreateProcessW", &DetourCreateProcessW, &fpCreateProcessW) != MH_OK)
      {
         return 1;
      }

      // Enable the hook for MessageBoxW.
      if (MH_EnableHook(&CreateProcessW) != MH_OK)
      {
         return 1;
      }

        break;
    case DLL_PROCESS_DETACH:
      // Disable the hook for MessageBoxW.
      if (MH_DisableHook(&CreateFileW) != MH_OK)
      {
         return 1;
      }

      // Disable the hook for MessageBoxW.
      if (MH_DisableHook(&CreateProcessW) != MH_OK)
      {
         return 1;
      }

      // Uninitialize MinHook.
      if (MH_Uninitialize() != MH_OK)
      {
         return 1;
      }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Mon Jul 13, 2015 4:08 pm    Post subject: Reply with quote

I'm not going to give you the lines of code you need to replace since that will teach you nothing, however, this is a guide line as to what you will need to do:

Overall:
- Rename your variables to properly understand that it is being used for CreateProcesA instead of W.
- Change your typedef to be the proper prototype for CreateProcessA.

Inside of DllMain:
- Change the hook code to look for CreateProcessA instead of CreateProcessW.

Inside of DetourCreateProcessW:
- This should be renamed to DetourCreateProcessA.
- Adjust this function to properly mimic the CreateProcessA prototype.
- Alter any wide-character calls you have to ansi variants of the same thing. (For example, wprintf should be sprintf.)
- Remove any wide-character casting, L's.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
rain-13
Expert Cheater
Reputation: 0

Joined: 18 Mar 2009
Posts: 110

PostPosted: Thu Jul 16, 2015 2:14 am    Post subject: Reply with quote

Tnx.

Quote:
Adjust this function to properly mimic the CreateProcessA prototype.

How do I do that?
Here it gives the same signature for both CreateProcessA and CreateProcessW.

Here's what I have done sofar.


Code:
#include <Windows.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include "MinHook.h"

#if defined _M_X64
#pragma comment(lib, "libMinHook.x64.lib")
#elif defined _M_IX86
#pragma comment(lib, "libMinHook.x86.lib")
#endif

// Helper function for MH_CreateHookApi().
template <typename T>
inline MH_STATUS MH_CreateHookApiEx(LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, T** ppOriginal)
{
    return MH_CreateHookApi(pszModule, pszProcName, pDetour, reinterpret_cast<LPVOID*>(ppOriginal));
}

typedef HANDLE (WINAPI *CREATEFILEW)(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
typedef BOOL (WINAPI *CREATEPROCESSA)(LPCTSTR, LPTSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCTSTR, LPSTARTUPINFO, LPPROCESS_INFORMATION);

// Pointer for calling original MessageBoxW.
CREATEFILEW fpCreteFileW= NULL;
CREATEPROCESSA fpCreateProcessA= NULL;

void createConsole(){
   int hCrt = 0;
   FILE* hf_out = NULL;
   HANDLE handle_in = NULL;
   FILE* hf_in = NULL;
   HANDLE handle_out = NULL;

   AllocConsole();
   handle_out = GetStdHandle(STD_OUTPUT_HANDLE);
   hCrt = _open_osfhandle((long) handle_out, _O_TEXT);
   hf_out = _fdopen(hCrt, "w");
   setvbuf(hf_out, NULL, _IONBF, 1);
   *stdout = *hf_out;
 
   handle_in = GetStdHandle(STD_INPUT_HANDLE);
   hCrt = _open_osfhandle((long) handle_in, _O_TEXT);
   hf_in = _fdopen(hCrt, "r");
   setvbuf(hf_in, NULL, _IONBF, 128);
   *stdin = *hf_in;
}

// Detour function which overrides MessageBoxW.
HANDLE WINAPI DetourCreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess,DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
   if(lpFileName != NULL){
      wprintf(L"File: %s %x %x\n",lpFileName, dwDesiredAccess, dwShareMode);
      if(wcscmp(lpFileName,L"C:\\Windows\\System32\\drivers\\etc\\hosts") == 0 && //Deny access to this one specific file
      dwDesiredAccess == 0xC0000000){
         return INVALID_HANDLE_VALUE;
      }
   }
    return fpCreteFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);

}

template<typename TypeA>
TypeA getStr(TypeA x){
   if(x == NULL){
      return "NULL";
   }
   return x;
}

template<typename TypeB>
TypeB getInt(TypeB x){
   if(x == NULL){
      return 0;
   }
   return x;
}


// Detour function which overrides MessageBoxW.
BOOL WINAPI DetourCreateProcessA(
  _In_opt_    LPCTSTR               lpApplicationName,
  _Inout_opt_ LPTSTR                lpCommandLine,
  _In_opt_    LPSECURITY_ATTRIBUTES lpProcessAttributes,
  _In_opt_    LPSECURITY_ATTRIBUTES lpThreadAttributes,
  _In_        BOOL                  bInheritHandles,
  _In_        DWORD                 dwCreationFlags,
  _In_opt_    LPVOID                lpEnvironment,
  _In_opt_    LPCTSTR               lpCurrentDirectory,
  _In_        LPSTARTUPINFO         lpStartupInfo,
  _Out_       LPPROCESS_INFORMATION lpProcessInformation
   )
{
   printf("sdfsdfds");
   if(&lpApplicationName != NULL){
      printf("Process: '%s' '%s' %X %X %d %X %X '%s' %X %X\n",getStr(lpApplicationName), getStr(lpCommandLine), getInt(lpProcessAttributes), getInt(lpThreadAttributes),
         getInt(bInheritHandles), getInt(dwCreationFlags), getInt(lpEnvironment), getStr(lpCurrentDirectory), getInt(lpStartupInfo), getInt(lpProcessInformation));
   }
    return fpCreateProcessA(lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,dwCreationFlags,lpEnvironment,lpCurrentDirectory,lpStartupInfo,lpProcessInformation);

}


INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved)
{
    switch(Reason)
    {
    case DLL_PROCESS_ATTACH:
      createConsole();
      // Initialize MinHook.
      if (MH_Initialize() != MH_OK)
      {
         return 1;
      }

      // Create a hook for MessageBoxW, in disabled state.
      if (MH_CreateHookApiEx(L"Kernel32", "CreateFileW", &DetourCreateFileW, &fpCreteFileW) != MH_OK)
      {
         return 1;
      }

      // Enable the hook for MessageBoxW.
      if (MH_EnableHook(&CreateFileW) != MH_OK)
      {
         return 1;
      }
      
      //process
      // Create a hook for MessageBoxW, in disabled state.
      if (MH_CreateHookApiEx(L"Kernel32", "CreateProcessA", &DetourCreateProcessA, &fpCreateProcessA) != MH_OK)
      {
         return 1;
      }

      // Enable the hook for MessageBoxW.
      if (MH_EnableHook(&CreateProcessA) != MH_OK)
      {
         return 1;
      }

        break;
    case DLL_PROCESS_DETACH:
      // Disable the hook for MessageBoxW.
      if (MH_DisableHook(&CreateFileW) != MH_OK)
      {
         return 1;
      }

      // Disable the hook for MessageBoxW.
      if (MH_DisableHook(&CreateProcessA) != MH_OK)
      {
         return 1;
      }

      // Uninitialize MinHook.
      if (MH_Uninitialize() != MH_OK)
      {
         return 1;
      }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}


And this is what visual studio says:
Code:
1>------ Build started: Project: inject_dev, Configuration: Release Win32 ------
1>  Source.cpp
1>Source.cpp(65): error C2440: 'return' : cannot convert from 'const char [5]' to 'LPCTSTR '
1>          Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>          Source.cpp(95) : see reference to function template instantiation 'TypeA getStr<LPCTSTR>(TypeA)' being compiled
1>          with
1>          [
1>              TypeA=LPCTSTR
1>          ]
1>Source.cpp(65): error C2440: 'return' : cannot convert from 'const char [5]' to 'LPTSTR '
1>          Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>          Source.cpp(95) : see reference to function template instantiation 'TypeA getStr<LPTSTR>(TypeA)' being compiled
1>          with
1>          [
1>              TypeA=LPTSTR
1>          ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

What do I need to do about this?
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Thu Jul 16, 2015 12:23 pm    Post subject: Reply with quote

You can find the exact signatures inside of the Windows header files. Write out 'CreateProcessA' then right-click it and go to definition in Visual Studio. That will take you to where the macros and full definitions of both the A/W versions are defined.

Be careful when you do this, do not edit those header files that open!

As for the errors you posted, you are trying to convert a character array to a constant character pointer. Rather then using a templated function that has little use in this case, just use the ternary operator, such as:

Code:
printf("Process: '%s' '%s' %X %X %d %X %X '%s' %X %X\n",(lpApplicationName == NULL) ? "NULL : lpApplicationName,


And if need be add a static casting to it to force the type on the "NULL".

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
rain-13
Expert Cheater
Reputation: 0

Joined: 18 Mar 2009
Posts: 110

PostPosted: Thu Jul 16, 2015 2:48 pm    Post subject: Reply with quote

Tnx,

But I dont understand why trenary operator works but templated function doesnt?

I wanted to use these to make code shorter.
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Thu Jul 16, 2015 8:59 pm    Post subject: Reply with quote

rain-13 wrote:
Tnx,

But I dont understand why trenary operator works but templated function doesnt?

I wanted to use these to make code shorter.


It's not that a templated function wont work, it's more of the fact that it's not needed. As for why it doesn't work your templated function is inheriting the type of the variable you pass it.

So for example, you had:
getStr(lpApplicationName)

This takes the type of lpApplicationName and uses it as the templated type which in this case is LPCTSTR

When it errors it shows the reason being:
'return' : cannot convert from 'const char [5]' to 'LPCTSTR '

From this, it is saying the your single const char array does not equate to the type LPCTSTR and no suitable conversions can be made.

If you want it to work for either type (unicode or ascii) then do something like this:
Code:
template<typename T>
T getStr(T input)
{
    return (input == nullptr) ? _T("NULL") : input;
}


Also be weary of your default character set in your projects settings. Macros that define with a T in them such as LPCTSTR are designed to be set based on the character set you are compiling against. So if you compile against unicode, LPCTSTR becomes 'const wchar_t*' and for ascii it becomes 'const char*'.

(You will need to include tchar.h in your project.)

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
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