DLL injection

Need Help With an Existing Feature in Memory Hacking Software? Ask Here

Moderators: g3nuin3, SpeedWing, WhiteHat, mezzo

DLL injection

Postby mezzo » Tue Nov 27, 2007 10:50 pm

heyhey, gotta small question (as usual) :D

After a DLL has been injected, is it possible to hijack a function in another DLL and point the old function to another one in the DLL that has been injected ?

If I compile a DLL, which contains a function with the exact same arguments and return values as lets say for example the messagebox function from the user32.dll, can I fool the program that's being MHS'd into running my function from the injected DLL instead of the regular messagebox function ? Further then that, is it possible to only run the custom function on certain occasions (when certain condition are true for example).

Are there any LSS functions available to do this ? Would breakpointing and scripting around the GetProcAddress function allow me to send the address of my function instead of the original function ?
(and when is this GetProcAddress function called ? when the DLL is originally loaded or each time the function is called ?)
- No thanks, I already have a penguin -
User avatar
mezzo
El Mariachi
 
Posts: 739
Joined: Mon Apr 30, 2007 10:27 pm
Location: Antwerp

Postby Shynd » Wed Nov 28, 2007 2:00 am

The way I do that is using the Microsoft Detours library (I prefer v1.5, personally). Here's a DLL that I wrote as a test of the functionality that I wanted to put into a game bot. It overwrites every call to kernel32:GetTickCount() with a call to a function in my DLL (which I then pass back to kernel32:GetTickCount(), but you could do whatever you wanted with it).
The DLL (main.cpp):
Code: Select all
#include <windows.h>
#include <stdio.h>
#include "main.h"
#include "detours.h"



//Our EVENT enumeration -- NoEvent is 0, the next is 1, 2, 3, etc.
enum EVENT
{
   NoEvent,
   MessageBoxEvent,
   HelpFileEvent
};



//our shared data segment, letting two programs simulatneously access Event
#pragma data_seg(".shared")
BYTE Event = 0;
#pragma data_seg()
#pragma comment(linker,"/SECTION:.shared,RWS")



//set up our GTK Trampoline for detour
typedef DWORD (__stdcall *GETTICKCOUNT)(void);
GETTICKCOUNT Old_GetTickCount = NULL;



//set up our notepad function Trampoline for detour
typedef DWORD (__stdcall *NOTEPADSOMETHING)(DWORD x, DWORD y, WORD z);
NOTEPADSOMETHING Old_NotepadSomething = NULL;

//our notepad function that we can call whenever we want
NOTEPADSOMETHING New_NotepadSomething(DWORD x, DWORD y, WORD z)
{
   return (NOTEPADSOMETHING)Old_NotepadSomething(x, y, z);
}



BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
   char szParentEXEName[255] = {0};

   GetModuleFileName(0, szParentEXEName, MAX_PATH);

   bool shouldattach = false;
   
   //only attach to notepad
   if (strstr(_strlwr(szParentEXEName), "\\notepad.exe") != NULL) shouldattach = true;

   if (ul_reason_for_call == DLL_PROCESS_ATTACH && shouldattach)
   {
      DisableThreadLibraryCalls(NULL);

      //detour our two functions
      Old_NotepadSomething = (NOTEPADSOMETHING)DetourFunction((PBYTE)0x1002B87, (PBYTE)New_NotepadSomething);
      Old_GetTickCount = (GETTICKCOUNT)DetourFunction((PBYTE)GetTickCount, (PBYTE)New_GetTickCount);

      return true;
   }
   else if (ul_reason_for_call == DLL_PROCESS_DETACH && shouldattach)
   {
      //remove detours
      DetourRemove((PBYTE)Old_NotepadSomething, (PBYTE)New_NotepadSomething);
      DetourRemove((PBYTE)Old_GetTickCount, (PBYTE)New_GetTickCount);
      return true;
   }

   return true;
}



DWORD WINAPI New_GetTickCount()
{
   __asm
   {
      pushad;
      pushfd;
   }

   if (Event > NoEvent)
   {
      //execute our event
      if (Event == MessageBoxEvent)
      {
         Event = NoEvent;
         MessageBox(NULL, "SLDKFLS", "SDKLFS", MB_OK);
      }
      else if (Event == HelpFileEvent)
      {
         Event = NoEvent;
         //open notepad's help file
         New_NotepadSomething(0x61238, 0x40, 0);
      }

      Event = NoEvent;
   }

   __asm
   {
      popfd;
      popad;
   }

   return Old_GetTickCount();
}



extern "C" __declspec(dllexport) DWORD SetNewEvent(BYTE newevent)
{
   Event = newevent;
   return Event;
}

extern "C" __declspec(dllexport) BOOL InjectDll(DWORD dwProcessId)
{
   HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, dwProcessId);
   return DetourContinueProcessWithDll(hProcess, "NotepadHijackerInject.dll");
}


The header (main.h):
Code: Select all
#define WIN32_LEAN_AND_MEAN

DWORD WINAPI New_GetTickCount(void);

extern "C" __declspec(dllexport) DWORD SetNewEvent(BYTE newevent);
extern "C" __declspec(dllexport) BOOL InjectDll(DWORD dwProcessId);


You can download Detours v1.5 from http://www.shynd.com/detours15/.


Basically, the above routes all GetTickCount calls through my DLL which checks to see if there's a new event in the event queue. If there's a new event, the proper action is taken--this allows us to call functions inside the process from an outside source. The DLL has a shared segment which is how you set the events to be taken. Anyway, I hope this helps you.



Edit: for the record, you don't have to detour any functions inside the process that you want to call; the only reason I did that was I was originally logging all calls to Old_NotepadSomething (I never did figure out what to name that function as I don't know what it does). You can far more easily call functions at a certain address by defining the function and then setting the function pointer to the address of the game function you want to call. Something like...
Code: Select all
//be sure that the return type and the parameters match the function you want to call
void (__stdcall * GameFunction)(DWORD *parameter1, DWORD *parameter2);

...

//move the address of the game function you want to call over the function you just defined
__asm{ mov GameFunction, 0x5BC508 };

..

//call the function with the correct number of parameters
GameFunction(parm1, parm2);
User avatar
Shynd
Acker
 
Posts: 68
Joined: Fri Jan 05, 2007 2:11 am

Postby mezzo » Wed Nov 28, 2007 5:55 pm

thanks mate ! didn't see this reply yesterday.. for some reason the board didn't show it when I viewed all new posts :?

Will check it out this evening, as all my collegues are out of the office and all hell just broke loose :shock:
- No thanks, I already have a penguin -
User avatar
mezzo
El Mariachi
 
Posts: 739
Joined: Mon Apr 30, 2007 10:27 pm
Location: Antwerp


Return to Help

Who is online

Users browsing this forum: No registered users and 0 guests

cron