хехе, вспомнилась дллка, давно давно писаная - чтоб вывод в ирке был разноцветный =)
Код:
/*
* XmasIRC patch for mIRC, ver 1.00
* Copyright (c) 2004-2005, The BOXP Developers Team. All Rights Reserved.
*
* Author: BD, sn0w at pc-r00m dot net
*/
#include <winsock2.h>
#include <stdio.h>
#include "resource.h"
#define _MSG(s) MessageBox(NULL, s, "debugFX", MB_OK|MB_ICONWARNING)
#define getrandom( min, max ) (( rand() % (int)((( max ) + 1 ) - ( min ))) + ( min ))
#define XMASIRC_MUTEX "XMASIRC_MUTEX"
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
void PatchMainWindow(HANDLE hMod);
void InterceptFunctions(void);
int WSAAPI Intercept_send(SOCKET s, const char FAR * buf, int len, int flags);
HANDLE hMutex;
#pragma pack(1) //sn0w: 1 byte member structure alignment (got crash otherwise) =))
struct jmp_far
{
BYTE instr_push; //здесь будет код инструкции push
DWORD arg; //аргумент push
BYTE instr_ret; //здесь будет код инструкции ret
};
#pragma pack()
BYTE old[6]; //область для хранения 6-ти затираемых байт начала функции
DWORD adr_send; //будущий адрес оригинальной функции
DWORD written; //вспомогательная переменная
jmp_far jump; //здесь будет машинный код инструкции перехода
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call,
LPVOID lpReserved )
{
// Если система подключает DLL к какому-либо процессу,
// она сначала вызовет главную функцию DLL с параметром
// DLL_PROCESS_ATTACH, на что мы сразу вызовем нашу функцию
// InterceptFunctions, которая произведет подмену стандартной API функции
if(ul_reason_for_call == DLL_PROCESS_ATTACH){
hMutex = CreateMutex(NULL, TRUE, XMASIRC_MUTEX);
if(hMutex != (HANDLE)ERROR_ALREADY_EXISTS){
InterceptFunctions();
PatchMainWindow(hModule);
}
}else if(ul_reason_for_call == DLL_PROCESS_DETACH){
ReleaseMutex(hMutex);
}
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
void InterceptFunctions(void)
{
//сначала получим абсолютный адрес функции для перехвата
adr_send = (DWORD)GetProcAddress(GetModuleHandle("ws2_32.dll"),
"send");
if(adr_send == 0){
_MSG("Cant get adr_send");
return;
}
// Зададим машинный код инструкции перехода, который затем впишем
// в начало полученного адреса:
// sn0w: (disassembly)
//
// push addr Intercept_send; ( push address to stack)
// ret ( pop eip from stack (fake call) )
//
// than i'll write this opcodes at the begin of send() in ws2_32 image in
// memory space.
jump.instr_push = 0x68;
jump.arg = (DWORD)&Intercept_send;
jump.instr_ret = 0xC3;
//Прочитаем и сохраним первые оригинальные 6 байт стандартной API функции
ReadProcessMemory(GetCurrentProcess(),(void*)adr_send,
(void*)&old, 6, &written);
//Запишем команду перехода на нашу функцию поверх этих 6-ти байт
WriteProcessMemory(GetCurrentProcess(), (void*)adr_send,
(void*)&jump, sizeof(jmp_far), &written);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
void XmasBuild(char *sDest, char *sSource)
{
char* s_prefix = "PRIVMSG #antichat :";
char sTo[9000];
int ncnt = 0;
while(*sSource){
if(getrandom(1,10)>=5){
sTo[ncnt++] = 0x03; //add color
sprintf(&sTo[ncnt++], "%.2d", getrandom(1,14)); // foreground
ncnt++;
// sprintf(&sTo[ncnt++], ",%d", getrandom(1,14)); // background
sTo[ncnt++] = *sSource;
}else{
sTo[ncnt++] = 0x02; //add bold
sTo[ncnt++] = *sSource;
}
sSource++;
}
sTo[ncnt] = 0;
strcpy(sDest, s_prefix);
strcat(sDest, sTo);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
int WSAAPI Intercept_send(SOCKET s, const char FAR * buf, int len, int flags)
{
//Сначала восстанавливаем 6 первых байт функции. Это не обязательное
// действие, просто мы решили подшутить над пользователем, и все
// сообщения функции MessageBoxA переделать на свои, поэтому нам придется
// вызвать оригинальную функцию, а для этого следует восстановить ее адрес:
int rc;
char* s_prefix = "PRIVMSG #antichat :";
WriteProcessMemory(GetCurrentProcess(), (void*)adr_send,
(void*)&old, 6, &written);
//edit buffer...
char editedbuf[9000];
if(strncmp(buf, s_prefix, strlen(s_prefix))==0){
XmasBuild(editedbuf, (char*)(buf+strlen(s_prefix)));
rc = ((int (WSAAPI*)(SOCKET, const char FAR *, int, int))adr_send)(s,editedbuf,strlen(editedbuf),flags);
//rc = ((int (WSAAPI*)(SOCKET, const char FAR *, int, int))adr_send)(s,buf,len,flags);
}else{
rc = ((int (WSAAPI*)(SOCKET, const char FAR *, int, int))adr_send)(s,buf,len,flags);
}
//Снова заменяем 6 байт функции на команду перехода на нашу функцию
WriteProcessMemory(GetCurrentProcess(), (void*)adr_send,
(void*)&jump, 6,&written);
//_MSG("WSAStartup()");
return rc;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
void PatchMainWindow(HANDLE hMod)
{
HWND hWnd;
char s_buff[256];
char s_total[512];
hWnd = FindWindow("mIRC", NULL);
if(!hWnd) // failed
return;
GetWindowText(hWnd, s_buff, 255);
strcpy(s_total, s_buff);
strcat(s_total, " - xmasirc v 1.0 is in runtime now");
SetWindowText(hWnd, s_total);
HICON hIcon;
hIcon = LoadIcon((HINSTANCE)hMod, MAKEINTRESOURCE(IDI_MIRCICON));
if(!hIcon)
_MSG("Cant load icon");
SendMessage(hWnd, WM_SETICON, ICON_SMALL,
(LPARAM)hIcon);
UpdateWindow(hWnd);
}