My last assignment was Dll Injection. We had to take a random process ID and if the application had winsock loaded, we were to intercept functions connect, recv, send, and closesocket and print the parameters.
After trying various methods and failing, e.g overwriting the IAT(Import Address Table) etc. I deceided to go the hard ,fickle way.
Here was the process described by a Microsoft research paper i found.
Create 2 functions, a Trampoline function and a Detour function.
- Create a Trampoline function
- Copy the first 5 bytes of the real function to the Trampoline function
- Add an unconditional jmp to the 6th byte of the real function
- Overwrite the real function with an unconditional jmp to your Detour function.
- At the end of your Detour function jump to the trampoline function.
Sounds kinda confusing. If you think that's bad look some of the code i wrote.
void CopyToTrampoline( LPVOID lpTargetFunction, LPVOID lpTrampoline , int offset ) {
DWORD old;
PBYTE pbActual = (PBYTE)lpTargetFunction;
PBYTE pbTramp = (PBYTE)lpTrampoline;
//make page writable
VirtualProtect( lpTrampoline, 5 + offset, PAGE_WRITECOPY, &old );
for(int i = 0; i < offset; ++i) {
*pbTramp++ = *pbActual++;
}
pbActual = (PBYTE)lpTargetFunction;
//set jump
*pbTramp++ = 0xe9;
*((DWORD*)pbTramp) = (pbActual + offset) - (pbTramp + 4);
//restore protections
VirtualProtect( lpTrampoline, 5 + offset, PAGE_EXECUTE, &old);
}
void Redirect(PVOID lpTargetFunction, PVOID lpDetourFuntion) {
DWORD old;
VirtualProtect( lpTargetFunction, 5, PAGE_WRITECOPY, &old);
//copy unconditional jump
*((PBYTE)lpTargetFunction) = 0xe9;
//copy the next 4 bytes
*((DWORD*)((PBYTE)lpTargetFunction+1)) = PtrToUlong(lpDetourFuntion) - (PtrToUlong(lpTargetFunction) + 5);
//restore
VirtualProtect( lpTargetFunction, 5, PAGE_EXECUTE, &old);
}
The worst thing about getting help online if when they show you a function but not how to use it, but i will not do the same :).
void Intercept(PVOID lpTargetFunction, PVOID lpTrampoline, LPVOID lpDetourFuntion, int offset) {
CopyToTrampoline( lpTargetFunction, lpTrampoline , offset);
Redirect( lpTargetFunction, lpDetourFuntion );
// Flush the instruction cache to make sure
// the modified code is executed.
FlushInstructionCache(GetCurrentProcess(), NULL, NULL);
}
//Intercepting connect function in winsock
//get winsock2 module
HMODULE hWinSock = GetModuleHandleA("ws2_32.dll");
if(hWinSock) {
Intercept( connect, ConnectTrampoline, MyConnect, 5 );
}
The ConnectTrampoline and MyConnect are both naked.
1 comment:
There is a lot more to this than I initially thought..
Shriram
Post a Comment