You can do this one of 2 ways, if your just hacking the dll itself with its own code (ie bytehacking) - fyi; you CAN bytehack a dll/exe, its very possible, you need to know asm.
1) Bytehacking the File: you could tell it to JMP to another area in the dll instead of Calling DllMain, of course it would crash but if you knew what you were doing it wouldnt crash you could make it do what you want.
2) Editing Memory: Remember the old md5 hacks for 2k4 that Clockwize released? Welcome back to the hell of trying to read over that source, but maybe this time you'll understand what it was doing.
it's doing exactly what i showed above^- just its doing it on the fly so it has to protect the memory and protect the registers otherwise the computer will freak out and scream "WTF ARE YOU TRYING TO DO, YOU CAN NOT VIOLATE ME WHEN I AM TRYING TO RUN A PROGRAM! OMG RAPE"
HMODULE hEng = GetModuleHandle("Engine.dll"); // Open Engine.dll for reading
DWORD TheSuperDuperHax0rOffset = (DWORD)GetProcAddress(hEng, "_DllMain@12"); // Our Hax0r Offset = where DllMain is in Engine.dll (0x105E18A4 - you could hard code this of course)
Now that you have the Location loaded into a Pointer you can use in your source you can VirtualProtect the next 5 bytes in memory
0xE8 = 1
0xF7 = 1
0x96 = 1
0xDB = 1
0xFF = 1
1 + 1 + 1 + 1 + 1 = 5
fill all 5 bytes with NOPS:
Protect your registers so you dont fuck up the stack!!!
__asm pushad ; push all registers
// do what you want here:
// in our case we shall:
__asm call MyHax0rDllMain
reset the registers again!
TADA YOUR DONE
thats several methods of Code Overwritting and 1 example of Detouring!
/me whipes sweat off forehead
Breakpoints via Debugger
breakpoints own! ok well sorta... they are great in so many ways but not (in my opinion) for hooking
debuggers give you an easy way to make use of them
A breakpoint stops (pauses) a program for an extended amount of time to give you the user time to do whatever you wish with the memory that you broke at without ****ing up the program
There are a few drawbacks to using this approach though as debugging a prog will suspend all application threads (will ... physically pause the program)
uh not the best hax0r method...
can also be done through code, too much of a waste to explain
Altering the IAT (Import Address Table)
This is a very clean and efficient way to hook almost anything, if you saw my Unreal Engine Hook tutorial you will see an example of Import Address Table hooking.
In order to make good use of IAT hooking you need to know a good deal about the Portable Executable (PE) Windows File Format and Common Object File Format (COFF)
The most important of the 2 however is the PE File Format, the PE file format is composed of 7 sections, just like our unreal file format is composed of certain things (Header, Name Table, Imports, Exports)
the most important part of the PE File Format is ".idata" .idata is in essence the Import Table and all of the data within it. When a program/module is made it has a lot of 'dependancies' just as our hacks have dependancies in say; 'engine' and 'core' -
Each dependancy in a Win32 application is called an Import (same as uscript)
The best way to determine all of the Imports of a application is to grab information (in an infinite loop) out of .idata - one would think that scanning through all of the imports of an application would bog down the hooking process and take considerable system resources, but thats what is so lovely about IAT, every import of said win32 application is located neatly and cleanly within the Import Address Table! Because it's just that, a Table, with offsets Imports and data, each one composed of nothing more than an indirect call to an import that is 'written' into the IAT with a simple JMP
Scan through .idata, find the function (offset, thunk, et al) that you want ->
and VirtualProtect it again - initalize your typedef and fill it with all the information from what the IAT points to and TADA you just hooked a win32 API Function in the most clean and efficient manner to date (imo)
heres a code snippet for ya'll who havent looked at my source:
typedef void (WINAPI *ProcessEvent_typedef)(class UFunction*,void*,void*);
// IAT MAJIC
void ReDirectFunction (char* strDllName, char* strFunctionName, DWORD newFuncAddy)
hEng = GetModuleHandleA("Engine.dll");
pDosHeader = PIMAGE_DOS_HEADER(hEng);
dwOffset = pDosHeader->e_lfanew;
pPeHeader = PIMAGE_NT_HEADERS(long(hEng) + dwOffset);
pOptionalHeader = &pPeHeader->OptionalHeader;
pDataDirectory = pOptionalHeader->DataDirectory;
dwOffset = pDataDirectory[IMAGE_DIRECTORY_ENTRY_IMPOR
pImportDescriptor = PIMAGE_IMPORT_DESCRIPTOR(long(hEng) + dwOffset);
for(dwIndex = 0; true; dwIndex++)
dwOffset = pImportDescriptor[dwIndex].Name;
strCurrent = PSTR(long(hEng) + dwOffset);
if(stricmp(strCurrent, strDllName) == 0) break;
dwOffset = pImportDescriptor[dwIndex].FirstThunk;
pdwIAT = PDWORD(long(hEng) + dwOffset);
dwOffset = pImportDescriptor[dwIndex].OriginalFirstTh
pdwINT = PDWORD(long(hEng) + dwOffset);
for(dwIndex = 0; true; dwIndex++)
dwOffset = pdwINT[dwIndex];
pImportName = PIMAGE_IMPORT_BY_NAME(long(hEng) + dwOffset);
strCurrent = PSTR(pImportName->Name);
if(stricmp(strCurrent, strFunctionName) == 0) break;
VirtualProtect(&pdwIAT[dwIndex], sizeof(DWORD), PAGE_READWRITE, &dwBackup);
orgProcessEvent = (PrEv)pdwIAT[dwIndex];
pdwIAT[dwIndex] = PtrToUlong(newFuncAddy);
VirtualProtect(&pdwIAT[dwIndex], sizeof(DWORD), dwBackup, &dwOffset);