#include "stdafx.h"
#include "windows.h"
#include <Shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")
#define AddSize 0x20000
unsigned
char
OepData[0x0042] =
{
0xeb, 0x10, 0x56, 0x4d, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x20, 0x62, 0x65, 0x67, 0x69,
0x6e, 0x00, 0x60, 0x9c, 0x64, 0xa1, 0x30, 0x00, 0x00, 0x00, 0x8b, 0x80, 0x00, 0x05, 0x00, 0x00,
0x83, 0xf8, 0x00, 0x74, 0x07, 0x50, 0xff, 0x15, 0x33, 0x71, 0x4b, 0x00, 0x9d, 0x61, 0xe9, 0xda,
0x55, 0xfa, 0xff, 0xeb, 0x0e, 0x56, 0x4d, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x20, 0x65,
0x6e, 0x64
};
DWORD
rva2offset(
LPVOID
base,
DWORD
rva)
{
IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)base;
IMAGE_NT_HEADERS32* ntHeader = (IMAGE_NT_HEADERS32*)(dosHeader->e_lfanew + (
DWORD
)base);
IMAGE_SECTION_HEADER* sectionHeader = (IMAGE_SECTION_HEADER*)((
DWORD
)ntHeader +
sizeof
(IMAGE_NT_HEADERS32));
if
(rva<ntHeader->OptionalHeader.SizeOfHeaders)
{
return
rva;
}
for
(
DWORD
i = 1; i <= ntHeader->FileHeader.NumberOfSections; i++)
{
if
(i == ntHeader->FileHeader.NumberOfSections)
{
return
rva - sectionHeader->VirtualAddress + sectionHeader->PointerToRawData;
}
else
if
(rva >= sectionHeader->VirtualAddress && rva < (sectionHeader + 1)->VirtualAddress)
{
return
rva - sectionHeader->VirtualAddress + sectionHeader->PointerToRawData;
}
sectionHeader++;
}
return
0;
}
DWORD
AddImprot(
char
*ModulePath)
{
HANDLE
hFile = CreateFileA(ModulePath, GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if
(hFile == 0 || hFile == INVALID_HANDLE_VALUE)
{
return
0;
}
DWORD
fileSize = GetFileSize(hFile, 0);
char
* buf =
new
char
[fileSize];
DWORD
ReadSize;
ReadFile(hFile, buf, fileSize, &ReadSize, NULL);
CloseHandle(hFile);
DWORD
New_File_Size = fileSize + AddSize;
PVOID
pNewTempBuffer = (
PVOID
)
malloc
(New_File_Size);
memset
(pNewTempBuffer, 0, New_File_Size);
memcpy
(pNewTempBuffer, buf, fileSize);
PIMAGE_NT_HEADERS32 ntHeader = (PIMAGE_NT_HEADERS32)((
DWORD
)pNewTempBuffer + ((PIMAGE_DOS_HEADER)(pNewTempBuffer))->e_lfanew);
if
((ntHeader->FileHeader.NumberOfSections + 1)*
sizeof
(IMAGE_SECTION_HEADER)>ntHeader->OptionalHeader.SizeOfHeaders)
{
printf
(
"剩余空间不足."
);
return
0;
}
PIMAGE_SECTION_HEADER newSection = (PIMAGE_SECTION_HEADER)(ntHeader + 1) + ntHeader->FileHeader.NumberOfSections;
memcpy
(newSection->Name,
"VMPLic"
, 8);
newSection->Characteristics = 0xE0000020;
newSection->Misc.VirtualSize = AddSize;
newSection->NumberOfLinenumbers = 0;
newSection->NumberOfRelocations = 0;
newSection->PointerToLinenumbers = 0;
newSection->PointerToRelocations = 0;
newSection->SizeOfRawData = AddSize;
DWORD
NewAddSize = (newSection - 1)->Misc.VirtualSize > (newSection - 1)->SizeOfRawData ?
(newSection - 1)->Misc.VirtualSize : (newSection - 1)->SizeOfRawData;
newSection->VirtualAddress = (newSection - 1)->VirtualAddress + NewAddSize;
if
(newSection->VirtualAddress % ntHeader->OptionalHeader.SectionAlignment)
{
newSection->VirtualAddress = newSection->VirtualAddress / ntHeader->OptionalHeader.SectionAlignment *
ntHeader->OptionalHeader.SectionAlignment + ntHeader->OptionalHeader.SectionAlignment;
}
newSection->PointerToRawData = (newSection - 1)->PointerToRawData + (newSection - 1)->SizeOfRawData;
if
(newSection->PointerToRawData % ntHeader->OptionalHeader.FileAlignment)
{
newSection->PointerToRawData = newSection->PointerToRawData / ntHeader->OptionalHeader.FileAlignment *
ntHeader->OptionalHeader.FileAlignment + ntHeader->OptionalHeader.FileAlignment;
}
DWORD
ImprotAddress = rva2offset(pNewTempBuffer, ntHeader->OptionalHeader.DataDirectory[1].VirtualAddress);
DWORD
ImprotSize = ntHeader->OptionalHeader.DataDirectory[1].Size;
char
* DLLname =
"VMProtectSDK32.dll"
;
char
* FunctionName =
"VMProtectSetSerialNumber"
;
memcpy
(
PVOID
((
DWORD
)pNewTempBuffer + fileSize),
PVOID
((
DWORD
)pNewTempBuffer + ImprotAddress), ImprotSize);
PIMAGE_IMPORT_DESCRIPTOR AddIMpoetAddr = (PIMAGE_IMPORT_DESCRIPTOR)((
DWORD
)pNewTempBuffer + fileSize + ImprotSize -
sizeof
(IMAGE_IMPORT_DESCRIPTOR));
AddIMpoetAddr->OriginalFirstThunk = newSection->VirtualAddress + ImprotSize +
sizeof
(IMAGE_IMPORT_DESCRIPTOR) +
strlen
(DLLname) + 1;
AddIMpoetAddr->FirstThunk = AddIMpoetAddr->OriginalFirstThunk +
sizeof
(IMAGE_THUNK_DATA32) * 2;
AddIMpoetAddr->ForwarderChain = 0;
AddIMpoetAddr->Name = newSection->VirtualAddress + ImprotSize +
sizeof
(IMAGE_IMPORT_DESCRIPTOR);
AddIMpoetAddr->TimeDateStamp = 0;
memcpy
((
PVOID
)((
DWORD
)pNewTempBuffer + fileSize + ImprotSize +
sizeof
(IMAGE_IMPORT_DESCRIPTOR)), DLLname,
strlen
(DLLname) + 1);
memcpy
((
PVOID
)((
DWORD
)pNewTempBuffer + fileSize + ImprotSize +
sizeof
(IMAGE_IMPORT_DESCRIPTOR) +
strlen
(DLLname) + 1 + 101 + 2), FunctionName,
strlen
(FunctionName) + 1);
DWORD
ByName = newSection->VirtualAddress + ImprotSize +
sizeof
(IMAGE_IMPORT_DESCRIPTOR) +
strlen
(DLLname) + 1 + 101;
DWORD
* OFT = PDWORD((
DWORD
)pNewTempBuffer + fileSize + ImprotSize +
sizeof
(IMAGE_IMPORT_DESCRIPTOR) +
strlen
(DLLname) + 1);
DWORD
* IAT = PDWORD((
DWORD
)pNewTempBuffer + fileSize + ImprotSize +
sizeof
(IMAGE_IMPORT_DESCRIPTOR) +
strlen
(DLLname) + 1 +
sizeof
(IMAGE_THUNK_DATA32) * 2);
*OFT = ByName;
*IAT = ByName;
ntHeader->FileHeader.NumberOfSections++;
ntHeader->OptionalHeader.SizeOfImage += AddSize;
DWORD
NewOep = newSection->VirtualAddress + ImprotSize +
sizeof
(IMAGE_IMPORT_DESCRIPTOR) +
strlen
(DLLname) + 1 + 101 + 200;
memcpy
(
PVOID
((
DWORD
)pNewTempBuffer + fileSize + ImprotSize +
sizeof
(IMAGE_IMPORT_DESCRIPTOR) +
strlen
(DLLname) + 1 + 101 + 200), OepData, 0x42);
PDWORD CallIat = PDWORD((
DWORD
)pNewTempBuffer + fileSize + ImprotSize +
sizeof
(IMAGE_IMPORT_DESCRIPTOR) +
strlen
(DLLname) + 1 + 101 + 200 + 0x28);
DWORD
C_value = AddIMpoetAddr->FirstThunk + ntHeader->OptionalHeader.ImageBase;
*CallIat = C_value;
PDWORD JmpOep = PDWORD((
DWORD
)pNewTempBuffer + fileSize + ImprotSize +
sizeof
(IMAGE_IMPORT_DESCRIPTOR) +
strlen
(DLLname) + 1 + 101 + 200 + 0x2F);
DWORD
J_value = ntHeader->OptionalHeader.AddressOfEntryPoint -
(newSection->VirtualAddress + ImprotSize +
sizeof
(IMAGE_IMPORT_DESCRIPTOR) +
strlen
(DLLname) + 1 + 101 + 200 + 0x2F) - 4;
*JmpOep = J_value;
ntHeader->OptionalHeader.AddressOfEntryPoint = NewOep;
ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;
ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
ntHeader->OptionalHeader.DataDirectory[1].VirtualAddress = newSection->VirtualAddress;
ntHeader->OptionalHeader.DataDirectory[1].Size = ImprotSize +
sizeof
(IMAGE_IMPORT_DESCRIPTOR);;
if
(0 != ntHeader->OptionalHeader.DataDirectory[1].VirtualAddress)
{
DWORD
RelocAddr = rva2offset(pNewTempBuffer, ntHeader->OptionalHeader.DataDirectory[5].VirtualAddress);
DWORD
RelocSize = ntHeader->OptionalHeader.DataDirectory[5].Size;
memcpy
(
PVOID
((
DWORD
)pNewTempBuffer + fileSize + ImprotSize + 1000),
PVOID
((
DWORD
)pNewTempBuffer + RelocAddr), RelocSize);
ntHeader->OptionalHeader.DataDirectory[5].VirtualAddress = newSection->VirtualAddress + +ImprotSize + 1000;
ntHeader->OptionalHeader.DataDirectory[5].Size = ntHeader->OptionalHeader.DataDirectory[5].Size;
DWORD
* RelocBase = PDWORD((
DWORD
)pNewTempBuffer + fileSize + ImprotSize + 1000 + ntHeader->OptionalHeader.DataDirectory[5].Size);
*RelocBase = newSection->VirtualAddress;
*(RelocBase + 1) = 0xC;
*(
PWORD
(RelocBase + 2)) = NewOep + 0x28 - newSection->VirtualAddress + 0x3000;
ntHeader->OptionalHeader.DataDirectory[5].Size += 0xC;
}
char
* newFileName = (ntHeader->FileHeader.Characteristics & IMAGE_FILE_DLL) ?
"New.dll"
:
"New.exe"
;
CHAR
parentPath[MAX_PATH];
CHAR
newPath[MAX_PATH];
PathRemoveFileSpecA(ModulePath);
lstrcpyA(parentPath, ModulePath);
PathCombineA(newPath, parentPath, newFileName);
HANDLE
hFile2 = CreateFileA(
newPath, GENERIC_WRITE | GENERIC_READ,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
DWORD
WriteSize = 0;
WriteFile(hFile2, pNewTempBuffer, New_File_Size, &WriteSize, NULL);
CloseHandle(hFile2);
}
int
main(
int
argc,
char
*argv[])
{
char
* filepath = argv[1];
AddImprot(filepath);
return
0;
}