用C++写的无源码给VMP添加授权工具【开源】
//借用了<无源码给程序加VMProtect授权>https://www.52pojie.cn/thread-417452-1-1.html 的汇编代码//支持多语言编译的exe不支持dll 和随机基址的exe
#include "stdafx.h"
#include "windows.h"
int GetPe(TCHAR* PeFileName, PVOID* FileBuffer){
TCHAR* FileName = PeFileName;
char* buf = nullptr;
HANDLE hFile;
DWORD dwFileSize;
DWORD ReadSize = 0;
hFile = CreateFile(
FileName, GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
dwFileSize = GetFileSize(hFile, NULL);
buf = new char;
ReadFile(hFile, buf, dwFileSize, &
ReadSize, NULL);
//by _ R-R,
PIMAGE_DOS_HEADER pDosH = (PIMAGE_DOS_HEADER)buf;
PIMAGE_NT_HEADERS32 pNtH = (PIMAGE_NT_HEADERS32)(buf + pDosH->e_lfanew);
PIMAGE_FILE_HEADER pFh = (PIMAGE_FILE_HEADER)((DWORD)pNtH+ 4);
PIMAGE_OPTIONAL_HEADER32 pOptH = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFh + IMAGE_SIZEOF_FILE_HEADER);
if (pDosH->e_magic != IMAGE_DOS_SIGNATURE)
{
MessageBoxW(NULL, L"DOS头错误!", L"Error", MB_OK);
CloseHandle(hFile);
return 0;
}
if (pNtH->Signature != IMAGE_NT_SIGNATURE)
{
MessageBoxW(NULL, L"NT头错误!", L"Error", MB_OK);
CloseHandle(hFile);
return 0;
}
*FileBuffer = buf;
buf = NULL;
CloseHandle(hFile);
return dwFileSize;
}
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_SECTION_HEADER pLastSection = NULL;
DWORD RVA_To_FOA(DWORD rva)
{
int offset = 0;
int i = 0;
if (rva<pOptionalHeader->SizeOfHeaders)
return rva;
PIMAGE_SECTION_HEADER ptempSection = pSectionHeader;
for (i = 0; i <= pPEHeader->NumberOfSections; i++, ptempSection++)
{
if (rva >= ptempSection->VirtualAddress &&
rva <= (ptempSection->VirtualAddress + ptempSection->SizeOfRawData))
break;
}
if (i > pPEHeader->NumberOfSections)
{
return 0;
}
offset = rva - ptempSection->VirtualAddress;
return ptempSection->PointerToRawData + offset;
}
int AddNec(PVOID OldBuf, DWORD OldSize, PVOID* NewBuf)
{
//by _ R-R,
const unsigned char CheckVmp[] =
{
0x33, 0xC9, 0x64, 0xA1, 0x30, 0x00, 0x00, 0x00,
0x8B, 0x40, 0x0C, 0x8B, 0x70, 0x1C, 0x8B, 0x46,
0x08, 0x8B, 0x7E, 0x20, 0x8B, 0x36, 0x66, 0x39,
0x4F, 0x18, 0x75, 0xF2, 0x8B, 0xD0, 0x8B, 0x42,
0x3C, 0x8B, 0x44, 0x10, 0x78, 0x03, 0xC2, 0x8B,
0x70, 0x20, 0x03, 0xF2, 0x68, 0x73, 0x73, 0x00,
0x00, 0x68, 0x64, 0x64, 0x72, 0x65, 0x68, 0x72,
0x6F, 0x63, 0x41, 0x68, 0x47, 0x65, 0x74, 0x50,
0x54, 0x33, 0xC9, 0x8B, 0x3E, 0x03, 0xFA, 0x56,
0x8B, 0x74, 0x24, 0x04, 0x51, 0xB9, 0x0F, 0x00,
0x00, 0x00, 0xF3, 0xA6, 0x74, 0x0B, 0x59, 0x5E,
0x83, 0xC6, 0x04, 0x41, 0x3B, 0x48, 0x18, 0x72,
0xE2, 0x59, 0x8B, 0x70, 0x24, 0x03, 0xF2, 0x0F,
0xB7, 0x0C, 0x4E, 0x8B, 0x70, 0x1C, 0x03, 0xF2,
0x8B, 0x34, 0x8E, 0x03, 0xF2, 0x8B, 0xFA, 0x6A,
0x00, 0x68, 0x61, 0x72, 0x79, 0x41, 0x68, 0x4C,
0x69, 0x62, 0x72, 0x68, 0x4C, 0x6F, 0x61, 0x64,
0x54, 0x52, 0xFF, 0xD6, 0xE8, 0x0D, 0x00, 0x00,
0x00, 0x6B, 0x65, 0x72, 0x6E, 0x65, 0x6C, 0x33,
0x32, 0x2E, 0x64, 0x6C, 0x6C, 0x00, 0x5B, 0x53,
0xFF, 0xD0, 0xE8, 0x19, 0x00, 0x00, 0x00, 0x47,
0x65, 0x74, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74,
0x65, 0x50, 0x72, 0x6F, 0x66, 0x69, 0x6C, 0x65,
0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x41, 0x00,
0x5B, 0x53, 0x50, 0xFF, 0xD6, 0xE8, 0x0A, 0x00,
0x00, 0x00, 0x2E, 0x5C, 0x4B, 0x65, 0x79, 0x2E,
0x69, 0x6E, 0x69, 0x00, 0x5B, 0x53, 0x68, 0x56,
0x02, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00,
0x5B, 0x83, 0xC3, 0x50, 0x53, 0x6A, 0x00, 0xE8,
0x04, 0x00, 0x00, 0x00, 0x4C, 0x69, 0x63, 0x00,
0x5B, 0x53, 0xE8, 0x09, 0x00, 0x00, 0x00, 0xCA,
0xDA, 0xC8, 0xA8, 0xCE, 0xC4, 0xBC, 0xFE, 0x00,
0x5B, 0x53, 0xFF, 0xD0, 0x8B, 0x44, 0x24, 0xF4,
0xE8, 0x07, 0x00, 0x00, 0x00, 0x90, 0xFF, 0x25,
0x11, 0x22, 0x33, 0x44, 0x90, 0x5B, 0x50, 0xFF,
0xD3, 0x90, 0x68, 0x00, 0x10, 0x40, 0x00, 0xC3,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
//by _ R-R,
PVOID buf = NULL;
DWORD dwFileSize = OldSize;
buf = OldBuf;
DWORD New_file_size = dwFileSize + 0x1000;
PVOID pNewTempBuffer = (PVOID)malloc(New_file_size);
if (!pNewTempBuffer)
{
printf("pNewTempBuffer开辟空间失败!\n");
return 0;
}
memset(pNewTempBuffer, 0, New_file_size);
memcpy(pNewTempBuffer, buf, dwFileSize);
pDosHeader = (PIMAGE_DOS_HEADER)(pNewTempBuffer);
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pNewTempBuffer + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pPEHeader->SizeOfOptionalHeader);
pLastSection = &pSectionHeader;
DWORD Remained_size = (DWORD)(pOptionalHeader->SizeOfHeaders -
pDosHeader->e_lfanew - 4 -
sizeof(PIMAGE_FILE_HEADER) -
pPEHeader->SizeOfOptionalHeader -
sizeof(PIMAGE_SECTION_HEADER)*pPEHeader->NumberOfSections);
if (Remained_size < 2 * sizeof(PIMAGE_SECTION_HEADER))
{
printf("exe文件头部剩余空间不足!\n");
free(pNewTempBuffer);
return 0;
}
PWORD pNumberOfSection = &pPEHeader->NumberOfSections;
PDWORD pSizeOfImage = &pOptionalHeader->SizeOfImage;
PVOID pSecName = &pSectionHeader.Name;
PDWORD pSecMisc = &pSectionHeader.Misc.VirtualSize;
PDWORD pSecVirtualAddress = &pSectionHeader.VirtualAddress;
PDWORD pSecSizeofRawData = &pSectionHeader.SizeOfRawData;
PDWORD pSecPointerToRawData = &pSectionHeader.PointerToRawData;
PDWORD pSecCharacteristic = &pSectionHeader.Characteristics;
*pNumberOfSection = pPEHeader->NumberOfSections + 1;
*pSizeOfImage = pOptionalHeader->SizeOfImage + 0x1000;
//by _ R-R,
memcpy(pSecName, ".VMP", 8);
*pSecMisc = 0x1000;
DWORD add_size = pLastSection->Misc.VirtualSize > pLastSection->SizeOfRawData ?
pLastSection->Misc.VirtualSize : pLastSection->SizeOfRawData;
*pSecVirtualAddress = pLastSection->VirtualAddress + add_size;
if (*pSecVirtualAddress % pOptionalHeader->SectionAlignment)
{
*pSecVirtualAddress = *pSecVirtualAddress / pOptionalHeader->SectionAlignment * pOptionalHeader->SectionAlignment + pOptionalHeader->SectionAlignment;
}
*pSecSizeofRawData = 0x1000;
*pSecPointerToRawData = pLastSection->PointerToRawData + pLastSection->SizeOfRawData;
if (*pSecPointerToRawData % pOptionalHeader->FileAlignment)
{
*pSecPointerToRawData = (*pSecPointerToRawData) / pOptionalHeader->FileAlignment * pOptionalHeader->FileAlignment + pOptionalHeader->FileAlignment;
}
*pSecCharacteristic = 0xE0000020;
DWORD ImprotAddress = RVA_To_FOA(pOptionalHeader->DataDirectory.VirtualAddress);
DWORD ImprotSize = pOptionalHeader->DataDirectory.Size;
DWORD NewImportAddress = *pSecVirtualAddress;
//by _ R-R,
PCHAR DllName = "VMProtectSDK32.dll";
PCHARFunctionName = "VMProtectSetSerialNumber";
DWORD Newsize = sizeof(IMAGE_IMPORT_DESCRIPTOR) +
sizeof(IMAGE_THUNK_DATA) +
(sizeof(DllName) + 1) +
(sizeof(FunctionName) + 1 + 2) +
ImprotSize;
PIMAGE_IMPORT_DESCRIPTOR pIMPORT = (PIMAGE_IMPORT_DESCRIPTOR)(((DWORD)pNewTempBuffer) + ImprotAddress);
PBYTE Newsection = PBYTE((DWORD)pNewTempBuffer + *pSecPointerToRawData);
memset(Newsection, 0, 0x1000);
int i = 0;
while (pIMPORT->FirstThunk != 0)
{
memcpy(Newsection, pIMPORT, sizeof(IMAGE_IMPORT_DESCRIPTOR));
pIMPORT++;
Newsection += sizeof(IMAGE_IMPORT_DESCRIPTOR);
i++;
}
memcpy(Newsection, (Newsection - sizeof(IMAGE_IMPORT_DESCRIPTOR)), sizeof(IMAGE_IMPORT_DESCRIPTOR));
DWORD NecRaw = *pSecPointerToRawData;
DWORD NecRva = *pSecVirtualAddress;
char hit = {0x00,0x01};
memcpy(Newsection + (sizeof(IMAGE_IMPORT_DESCRIPTOR) * 2), DllName, strlen(DllName));
memcpy(Newsection + (sizeof(IMAGE_IMPORT_DESCRIPTOR) * 2) + strlen(DllName) , hit, 2);
memcpy(Newsection + (sizeof(IMAGE_IMPORT_DESCRIPTOR) * 2) + strlen(DllName) + 3, FunctionName, strlen(FunctionName));
DWORD ThunkData = (((DWORD)(Newsection + (sizeof(IMAGE_IMPORT_DESCRIPTOR) * 2) + strlen(DllName) + 1)) -
(DWORD)pNewTempBuffer) - NecRaw + NecRva;
memcpy(Newsection + (sizeof(IMAGE_IMPORT_DESCRIPTOR) * 2) + strlen(DllName) + 3 + 8 + strlen(FunctionName), &ThunkData, 4);
DWORD Ofts = (((DWORD)(Newsection + (sizeof(IMAGE_IMPORT_DESCRIPTOR) * 2) + strlen(DllName) + 3 + 8 + strlen(FunctionName))) -
(DWORD)pNewTempBuffer) - NecRaw + NecRva;
DWORD name = (((DWORD)(Newsection + (sizeof(IMAGE_IMPORT_DESCRIPTOR) * 2))) -
(DWORD)pNewTempBuffer) - NecRaw + NecRva;
memcpy(Newsection, &Ofts, 4);
memcpy(Newsection + 16, &Ofts, 4);
memcpy(Newsection + 12, &name, 4);
PBYTE ShellAddress = Newsection + (sizeof(IMAGE_IMPORT_DESCRIPTOR) * 2) + strlen(DllName) + 3 + 8 + strlen(FunctionName) + 100;
memcpy(ShellAddress, CheckVmp, sizeof(CheckVmp));
DWORD NewOep = (DWORD)ShellAddress - (DWORD)pNewTempBuffer - NecRaw + NecRva;
DWORD OldOep = pOptionalHeader->AddressOfEntryPoint + pOptionalHeader->ImageBase;
printf("%s\n%x", "原始OEP地址,可作为保护代码", OldOep);
DWORD VMPset = Ofts + pOptionalHeader->ImageBase;
memcpy(ShellAddress + 272, &VMPset,4);
memcpy(ShellAddress + 283, &OldOep, 4);
pOptionalHeader->AddressOfEntryPoint = NewOep;
pOptionalHeader->DataDirectory.Size = pOptionalHeader->DataDirectory.Size + 8;
pOptionalHeader->DataDirectory.VirtualAddress = NewImportAddress;
//by _ R-R,
*NewBuf = pNewTempBuffer;
pNewTempBuffer = NULL;
return New_file_size;
}
void Write(PVOID wBuf,DWORD wSize){
PVOID Wbuffer = NULL;
DWORD wbSize = 0;
Wbuffer = wBuf;
wbSize = wSize;
//by _ R-R,
HANDLE hFile2 = CreateFile(
_T(".\\2.exe"), GENERIC_WRITE | GENERIC_READ,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
DWORD WriteSize = 0;
WriteFile(hFile2, Wbuffer, wbSize, &WriteSize, NULL);
CloseHandle(hFile2);
}
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR *PePatch = _T(".\\1.exe");
DWORD OldFileSize = 0;
PVOID OldFileBuf = NULL;
//by _ R-R,
OldFileSize = GetPe(PePatch, &OldFileBuf);
PVOID NewBuffer = NULL;
DWORD NewSize = 0;
NewSize =AddNec(OldFileBuf, OldFileSize, &NewBuffer);
Write(NewBuffer, NewSize);
getchar();
return 0;
}
测试了好几天…自己的exe一直无法授权
就连运行vmpro所得到的oep码,输入vmprotect,找不到这个进程oep
觉得很奇怪
后来随便弄了一个exe档後,就可以正常使用了
我的电脑是windowns 10、vmprotect测试版本是3.6
不过,我发现有一个问题
如果我在“添加授权”这个步骤,若是勾选使用次数5次的话
运行2.vmp.exe超过5次,还可以正常使用 测试了一下,VMP3.5版本,可以使用,但最高只能使用RSA3072算法;超过3072后,会始终认为无序列号或者序列号不正确(也许是序列号长度超过楼主的预期?希望楼主能修复这个问题) 不错,感谢分享 虽然不懂,但是肯定狠厉害。:lol 虽然不懂,但是肯定狠厉害。 很不错,收藏了。。。 都能给什么文件添加授权 厉害是厉害,但为啥你要一行一行的复制粘贴:Dweeqw。看着好别扭。哈哈哈哈哈哈哈 支持哪些版本的VMP啊? 键盘 发表于 2020-12-22 07:56
厉害是厉害,但为啥你要一行一行的复制粘贴。看着好别扭。哈哈哈哈哈哈哈
因为读取key文件不支持换行符 R-R, 发表于 2020-12-22 09:39
因为读取key文件不支持换行符
批量替换换行符了解下{:1_918:}