吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 15137|回复: 94
上一主题 下一主题
收起左侧

[Packers] 一个比较完整稳定的VMP授权添加工具,有码。

    [复制链接]
跳转到指定楼层
楼主
R-R, 发表于 2024-1-12 19:34 回帖奖励
<0>这是一个还算完整的VMP添加授权工具,比之前开源的版本修复了稳定性和不便性。和支持DLL。
<1>首先打开VMP_LIC工具如下图,然后选择要加密的文件。

<2>选择可执行文件后,目录下会多出一个new.exe或者dll的修改文件,目录下的VMSDK是在vmp目录下的 因为不加密的话打不开加密后的文件,
需要放置dll进去,加密后可以不需要这个vmpsdk的dll了,VMProtectSDK32.dll可以在论坛里面的3.x里面获取
可以看到下图,我构建了一段汇编,在里面添加了
VMProtectSetSerialNumber函数,并用PEB+0x500的地址作为参数用来传递key,这样做的好处是我可以写一个dll,dll用来获取机器码和key,
然后把key的地址放到PEB+0X500传进去,这样就达到了一键授权。

<3>再得到new.exe后用vmp加密,加密时锁定原来的oep,也可以自己添加任意地址锁定序列号。如下图

<4>这样加密后序列号锁定了,但由于没有获取到机器码和置入序列号,以下代码是一个获取机器码和置入序列号简版,你们可以用来修改。
[C++] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include "VMProtectSDK.h"
#pragma comment(lib, "VMProtectSDK32.lib")
 
char ** LicAddr = NULL;
 
void __stdcall GetFs()
{
    __asm
    {
        mov eax, dword ptr fs : [0x30]
        lea eax, dword ptr ds : [eax + 0x500]
        mov LicAddr, eax;
    }
 
}
 
void ReadLicense()
{
    HANDLE hLicFile = CreateFileA("License.Lic", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
    if (INVALID_HANDLE_VALUE == hLicFile)
    {
        MessageBoxA(NULL, "Lic文件出错!", "Error", MB_OK);
    }
    DWORD LicSize;
    LicSize = GetFileSize(hLicFile, NULL);
    if (0 == LicSize)
    {
        MessageBoxA(NULL, "Lic文件内容为空!", "Error", MB_OK);
    }
    char* LicBuf = new char[LicSize + 1];
    DWORD ReadSize;
    ReadFile(hLicFile, LicBuf, LicSize, &ReadSize, NULL);
    CloseHandle(hLicFile);
    GetFs();
    *LicAddr = LicBuf;
}
 
 
void GetHwid_()
{
    DWORD HwidSize = VMProtectGetCurrentHWID(NULL, 0);
    char * HwidStr = new char[HwidSize + 1];
    VMProtectGetCurrentHWID(HwidStr, HwidSize);
    MessageBoxA(NULL, HwidStr, "机器码", MB_OK);
    ReadLicense();
}
 
BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
    )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        GetHwid_();
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}


<5>代码里面的VMProtectSDK.h和VMProtectSDK32.lib 都可以再论坛的VMP3.X里面获取得到,dll编译出来后需要加密以下,因为调用了vmp的sdk,需要加密来获取机器码,
再加密的时候,保护选项全部选否,这个可以只加密一次,因为这个只是获取机器码和置入key的工具,如下图,

<6>在dll弄好之后,可以用vmp的dllbox来封装他,如果你不喜欢有外置dll来获取机器码那些,这样就达到了对exe或dll加密后仍然是一个单文件的形式,
在放置dll进去的时候选择启动时载入,如下图

<7>加密出来后就是一个单文件的new.vmp.exe了,当你运行时会弹出机器码,没有key时会写出License.Lic文件,
你在vmp里面算号后把key放入License.Lic里即可(KEY不要有换行符)
如下图

<8>主程序代码如下,是控制台代码,我编译了一份MFC的程序。
[C++] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
// Lic.cpp : 定义控制台应用程序的入口点。
//
 
#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;
}

<9>大致总结,虽然我说了这么多,但使用起来应该很简单,
第一步:用VMP_LIC选择要加密的文件,然后写出new.exe的新文件后,放到vmp里加密,加密时要初始化授权,然后锁定源程序oep。
第二步:把dll编译好如我上加密后可以一只使用这个dll,你可以任意修改这个dll,甚至加上sdk等。
第三步:dll导入进去选择启动时载入,很简单的三步,其实很方便,在源代码的基础上也可以任意修改。
当然,也可以根据这个思路写一份x64的版本。
以下是我用MFC编译的主程序,其他的没什么了。

VMP_LIC.rar

1.32 MB, 下载次数: 741, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 19吾爱币 +31 热心值 +15 收起 理由
fruitg + 1 + 1 我很赞同!
蚁上火 + 1 能不能把编驿好的dll也发上来
不是妖精 + 1 没啥用 修改本地时间就失效了,这个验证没有用
aaqunz + 1 我很赞同!
xiaoweng + 1 + 1 真的太牛了!
北城。 + 1 桥桥你挑粪去了啊
david891024 + 1 + 1 我很赞同!
cxn1ce + 1 + 1 谢谢@Thanks!
Hmily + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
zhczf + 1 + 1 我很赞同!
hunfeifei + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
fangchang819 + 1 + 1 谢谢@Thanks!
doublet + 1 + 1 我很赞同!
Hou + 1 + 1 谢谢@Thanks!
秋名山 + 1 + 1 谢谢@Thanks!
杨辣子 + 1 + 1 谢谢@Thanks!
Monitor + 3 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
凉游浅笔深画眉 + 3 + 1 又学到一招
bypasshwid + 3 + 1 高清无码!错了,有高清有码!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

头像被屏蔽
推荐
zhaode 发表于 2024-1-15 21:22
提示: 作者被禁止或删除 内容自动屏蔽
推荐
ianlcc 发表于 2024-1-15 12:34
很感谢楼主的分享!
这样子让没有源码的人可以试着用这个方式达到一机一码的方式…
希望有人可以分享一下创建的vmp.dll for x86&x64
沙发
95877133 发表于 2024-1-12 19:39
3#
HUHU666 发表于 2024-1-12 20:00
这个软件非常好!
4#
ssw12500 发表于 2024-1-12 20:04
感谢大佬分享
5#
Hou 发表于 2024-1-12 20:36
请教一下安全性如何?
6#
yuangao 发表于 2024-1-12 20:39
这样干, 就是文件很大..
7#
CQGaxm 发表于 2024-1-12 20:40
感谢分享,不错的教程
8#
lies2014 发表于 2024-1-12 20:44
谢谢分享!
9#
95877133 发表于 2024-1-12 21:00
有脱vmp的教程吗
10#
yaoguen 发表于 2024-1-12 21:00
多谢分享,希望支持x64
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-5-28 15:09

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表