EDIT: my question actually lies in [Only registered and activated users can see links. Click Here To Register...] now.
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include <WinSock2.h>
#include <shellapi.h>
#include "Detours\\src\\detours.h"
#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "Detours\\lib\\detours.lib")
#pragma comment(lib, "Detours\\lib\\detoured.lib")
int (WINAPI *OriginalConnect)(SOCKET s, const sockaddr *name, int len) = connect;
HINSTANCE (WINAPI *OriginalShell)(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, int nShowCmd) = ShellExecuteA;
HINSTANCE WINAPI DetouredShell(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, int nShowCmd)
{
if(strcmp("http://co.91.com/signout/", lpFile) == 0)
{
lpFile = "http://www.google.com";
}
return OriginalShell(hWnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd);
}
int WINAPI DetouredConnect(SOCKET s, const sockaddr *name, int len)
{
MessageBox(NULL, L"read in socket",NULL, NULL );
return OriginalConnect(s, name, len);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)OriginalConnect, DetouredConnect);
DetourAttach(&(PVOID&)OriginalShell, DetouredShell);
DetourTransactionCommit();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
#ifndef ASMBUILDER_H
#define ASMBUILDER_H
#include <windows.h>
#include <stdarg.h>
#include <sstream>
class AsmBuilder {
public:
AsmBuilder& reset() { os.str(""); return *this; }
AsmBuilder& ADD_EAX(int value) { BYTE(0x05).DWORD(value); return *this; }
AsmBuilder& SUB_EAX(int value) { BYTE(0x2D).DWORD(value); return *this; }
AsmBuilder& PUSH_EAX() { BYTE(0x50); return *this; }
AsmBuilder& POP_EAX() { BYTE(0x58); return *this; }
AsmBuilder& PUSHAD() { BYTE(0x60); return *this; }
AsmBuilder& POPAD() { BYTE(0x61); return *this; }
AsmBuilder& PUSH(int value) { BYTE(0x68).DWORD(value); return *this; }
AsmBuilder& PUSH_ARGS(int numParams, int arg1, ...) {
int params[numParams];
params[0] = arg1;
va_list argp;
va_start(argp, arg1);
for (int i = 1; i < numParams; ++i) {
params[i] = va_arg(argp, int);
}
va_end(argp);
for (int i = numParams-1; i >= 0; --i) {
PUSH(params[i]);
}
return *this;
}
AsmBuilder& JZ_SHORT_NEXT_EIP_PLUS(char direction) { return BYTE(0x74).BYTE(direction); }
AsmBuilder& MOV_ADDRESS_ESP(int address) { BYTE(0x89).BYTE(0x25).DWORD(address); return *this; }
AsmBuilder& ADD_ESP(int value) { return BYTE(0x81).BYTE(0xC4).DWORD(value); }
AsmBuilder& TEST_EAX_EAX() { return BYTE(0x85).BYTE(0xC0); }
AsmBuilder& POP_DWORD_PTR_EAX() { BYTE(0x8F).BYTE(0x00); return *this; }
AsmBuilder& POP_WORD_PTR_EAX() { BYTE(0x66).BYTE(0x8F).BYTE(0x00); return *this; }
AsmBuilder& MOV_EAX_ASM_START() { BYTE(0xE8).DWORD(0).POP_EAX().SUB_EAX(5 + getCodeSize()); }
AsmBuilder& MOV_EAX(int dword) { BYTE(0xB8).DWORD(dword); return *this; }
AsmBuilder& MOV_ECX(int dword) { BYTE(0xB9).DWORD(dword); return *this; }
AsmBuilder& RETN() { BYTE(0xC3); return *this; }
AsmBuilder& INT3() { BYTE(0xCC); return *this; }
AsmBuilder& CALL_NEXT_EIP_PLUS(int distance) { BYTE(0xE8).DWORD(distance); return *this; }
AsmBuilder& CALL(int address) { BYTE(0xE8).DWORD(0).DWORD(0x0AE40483).PUSH(address).RETN(); return *this; }
AsmBuilder& CALL_KERNEL32_FUNC(const char* funcName) {
CALL((int)GetProcAddress(GetModuleHandle("kernel32.dll"), funcName));
return *this;
}
AsmBuilder& CALL_REMOTE_PROCESS_FUNC(int processId, int funcAddress, int param) {
PUSHAD()
.PUSH_ARGS(3, PROCESS_ALL_ACCESS, 0, processId)
.CALL_KERNEL32_FUNC("OpenProcess")
.PUSH_EAX()
.PUSH(0)
.PUSH(0)
.PUSH(param)
.PUSH(funcAddress)
.PUSH(0)
.PUSH(0)
.PUSH_EAX()
.CALL_KERNEL32_FUNC("CreateRemoteThread")
.PUSH_EAX()
.PUSH(-1)
.PUSH_EAX()
.CALL_KERNEL32_FUNC("WaitForSingleObject")
.CALL_KERNEL32_FUNC("CloseHandle")
.CALL_KERNEL32_FUNC("CloseHandle")
.POPAD();
return *this;
}
AsmBuilder& JMP(int address) { PUSH(address).RETN(); return *this; }
AsmBuilder& JMP_NEXT_EIP_PLUS(int distance) { BYTE(0xE9).DWORD(distance); return *this; }
AsmBuilder& PUSH_DWORD_PTR_ESP() { BYTE(0xFF).BYTE(0x34).BYTE(0xE4); return *this; }
AsmBuilder& CALL_EAX() { BYTE(0xFF).BYTE(0xD0); return *this; }
AsmBuilder& PUSH_DWORD_PTR_ESP_PLUS(char offset) { BYTE(0xFF).BYTE(0x74).BYTE(0xE4).BYTE(offset); return *this; }
AsmBuilder& BYTE(char byte) { os.write(&byte, 1); return *this; }
AsmBuilder& WORD(short word) { os.write((char*)&word, 2); return *this; }
AsmBuilder& DWORD(int dword) { os.write((char*)&dword, 4); return *this; }
AsmBuilder& CODE(const char* code, int codeSize) { os.write(code, codeSize); return *this; }
const char* getCode() const { return os.str().c_str(); }
int getCodeSize() const { return os.str().length(); }
private:
std::ostringstream os;
};
#endif // ASMBUILDER_H
#include "AsmBuilder.h"
typedef HINSTANCE (WINAPI *ShellFn)(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, int nShowCmd);
static ShellFn OriginalShell;
static ShellFn CallbackShell;
static HINSTANCE WINAPI MyShell(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, int nShowCmd);
static AsmBuilder shellFixupCode;
static void installShellHook() {
OriginalShell = (ShellFn)GetProcAddress(GetModuleHandleA("shell32.dll"), "ShellExecuteA");
AsmBuilder code;
code.JMP((int)MyShell);
// To fix up the overridden code (hex copied from ollydbg)
char overriddenCode[] = {0x8B, 0xFF, 0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x40};
shellFixupCode.CODE(overriddenCode, sizeof(overriddenCode));
shellFixupCode.JMP((int)OriginalShell + shellFixupCode.getCodeSize());
DWORD old;
VirtualProtect(const_cast<char*>(shellFixupCode.getCode()), shellFixupCode.getCodeSize(), PAGE_EXECUTE_READWRITE, &old);
CallbackShell = (ShellFn)shellFixupCode.getCode();
VirtualProtect((void*)OriginalShell, code.getCodeSize(), PAGE_EXECUTE_WRITECOPY, &old);
memcpy((void*)OriginalShell, code.getCode(), code.getCodeSize());
VirtualProtect((void*)OriginalShell, code.getCodeSize(), old, &old);
}
HINSTANCE WINAPI MyShell(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, int nShowCmd) {
if(strcmp("http://co.91.com/signout/", lpFile) == 0) {
lpFile = "http://www.google.com";
}
return CallbackShell(hWnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
installShellHook();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Detours = less work assuming you already have it installed.Quote:
Detours is a waste, just do your own WriteProcessMemory to patch the function prologue to JMP to your own detoured function, easy as that.