![]() |
|
#17
|
||||
|
||||
|
@axl936: And once you have managed to unpack it you should take a look at my 'quick and dirty' patcher/keyfilemaker implementation. I've successfully tested the patcher with both versions (stable and development). The following steps are performed:
The main advantage of this procedure is that it should also work with future versions and different keys (as long as 1024bit RSA keys are used and the blob is stored as "BIN" resource). But you can easily modify the sources by redefining KEYLENGTH and BLOBRSRC - just in case they change the key size or the resource location. Code:
#include <windows.h>
#include <wincrypt.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#define KEYLENGTH (1024 << 16)
#define BLOBRSRC "BIN"
static LPBYTE lpbyTargetBlob = NULL;
BOOL CALLBACK EnumResNameProc(HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lParam)
{
HRSRC hrsrc;
HGLOBAL hBlob;
LPBYTE lpbyResource;
BOOL fRetVal = TRUE;
hrsrc = FindResourceA(hModule, lpszName, lpszType);
if (!hrsrc || SizeofResource(hModule, hrsrc) != (DWORD)lParam) return fRetVal;
if (!(hBlob = LoadResource(hModule, hrsrc))) return fRetVal;
lpbyResource = (LPBYTE)LockResource(hBlob);
if (!memcmp(lpbyResource + 8, "RSA2", 4))
{
lpbyTargetBlob = (LPBYTE)malloc(lParam);
memcpy(lpbyTargetBlob, lpbyResource, (DWORD)lParam);
fRetVal = FALSE;
}
UnlockResource(hBlob);
FreeResource(hBlob);
return fRetVal;
}
void main(int argc, char* argv[])
{
LPCSTR szLicense = "zementmischer\0Don't mess with concrete!!!\0forum.exetools.com\0\1\1\1\107";
CHAR szContainerName[_MAX_PATH] = "";
HCRYPTPROV hProv;
HCRYPTKEY hRSAKey;
LPBYTE lpbyPrivKeyBlob, lpbyLicense, lpbyFileMapping = NULL;
DWORD cbBlockSize, cbSize, cbPrivKeyBlob = 0, cbContainerName = sizeof(szContainerName), i;
HANDLE hFile = INVALID_HANDLE_VALUE, hFileMapping = NULL;
HMODULE hTarget;
BOOL fSuccess = FALSE;
if (argc != 2)
{
fprintf(stderr, "%s: <unpacked exe>\n", argv[0]);
return;
}
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0))
{
if (GetLastError() != NTE_BAD_KEYSET
|| !CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)
|| !CryptGetProvParam(hProv, PP_CONTAINER, (LPBYTE)szContainerName, &cbContainerName, 0))
{
fprintf(stderr, "Failed to open/create key container\n");
return;
}
}
if (!CryptGenKey(hProv, CALG_RSA_KEYX, KEYLENGTH | CRYPT_EXPORTABLE, &hRSAKey)
|| !CryptExportKey(hRSAKey, NULL, PRIVATEKEYBLOB, 0, NULL, &cbPrivKeyBlob))
{
fprintf(stderr, "Failed to generate RSA key pair\n");
goto cleanup;
}
lpbyPrivKeyBlob = (LPBYTE)_alloca(cbPrivKeyBlob);
CryptExportKey(hRSAKey, NULL, PRIVATEKEYBLOB, 0, lpbyPrivKeyBlob, &cbPrivKeyBlob);
CryptGetKeyParam(hRSAKey, KP_BLOCKLEN, (LPBYTE)&cbBlockSize, &cbSize, 0);
cbBlockSize = cbBlockSize / 8;
lpbyLicense = (LPBYTE)_alloca(cbBlockSize);
hFile = CreateFileA("license.dat", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "Failed to create license file\n");
goto cleanup;
}
memset(lpbyLicense, 0, cbBlockSize);
memcpy(lpbyLicense, szLicense, cbBlockSize - 12);
cbSize = cbBlockSize - 11;
CryptEncrypt(hRSAKey, NULL, FALSE, 0, lpbyLicense, &cbSize, cbBlockSize);
WriteFile(hFile, lpbyLicense, cbSize, &cbSize, NULL);
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
hTarget = LoadLibraryA(argv[1]);
if (!hTarget)
{
fprintf(stderr, "Failed to load target file\n");
goto cleanup;
}
EnumResourceNamesA(hTarget, BLOBRSRC, EnumResNameProc, cbPrivKeyBlob);
FreeLibrary(hTarget);
if (!lpbyTargetBlob)
{
fprintf(stderr, "Failed to locate RSA blob\n");
goto cleanup;
}
hFile = CreateFileA(argv[1], GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "Failed to open target file\n");
goto cleanup;
}
cbSize = GetFileSize(hFile, NULL);
if ((hFileMapping = CreateFileMappingA(hFile, NULL, PAGE_READWRITE, 0, 0, NULL)) != NULL
&& (lpbyFileMapping = reinterpret_cast<LPBYTE>(MapViewOfFile(hFileMapping, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, 0))) != NULL)
{
for (i = 0; i < cbSize - cbPrivKeyBlob; ++i)
{
if (!memcmp(lpbyFileMapping + i, lpbyTargetBlob, cbPrivKeyBlob))
{
memcpy(lpbyFileMapping + i, lpbyPrivKeyBlob, cbPrivKeyBlob);
fSuccess = TRUE;
break;
}
}
FlushViewOfFile(lpbyFileMapping, 0);
UnmapViewOfFile(lpbyFileMapping);
}
cleanup:
if (hFileMapping) CloseHandle(hFileMapping);
if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
if (lpbyTargetBlob) free(lpbyTargetBlob);
CryptDestroyKey(hRSAKey);
CryptReleaseContext(hProv, 0);
if (fSuccess) fprintf(stdout, "File patched\n");
}
__________________
Real programmers don't read manuals. Reliance on a reference is a hallmark of the novice and the coward. |
| Thread Tools | |
| Display Modes | |
|
|