Exetools  

Go Back   Exetools > General > General Discussion

Notices

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #17  
Old 08-03-2012, 02:43
zementmischer's Avatar
zementmischer zementmischer is offline
Don't mess with concrete
 
Join Date: Mar 2011
Location: Europe
Posts: 216
Rept. Given: 124
Rept. Rcvd 490 Times in 111 Posts
Thanks Given: 13
Thanks Rcvd at 103 Times in 33 Posts
zementmischer Reputation: 400-499 zementmischer Reputation: 400-499 zementmischer Reputation: 400-499 zementmischer Reputation: 400-499 zementmischer Reputation: 400-499
@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:
  1. Generate a random 1024bit RSA key pair.
  2. Generate a fresh license with this random key and save it as 'license.dat'.
  3. Open the unpacked target and locate the resource which holds the private key blob.
  4. Replace the private key with your own one and save the modifications back to the executable.

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.
Reply With Quote
The Following 4 Users Gave Reputation+1 to zementmischer For This Useful Post:
*RemedY* (08-03-2012), axl936 (08-03-2012), giv (08-03-2012), RedBlkJck (08-03-2012)
 


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



All times are GMT +8. The time now is 00:51.


Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX, chessgod101
( Since 1998 )