138 lines
3.2 KiB
C++
138 lines
3.2 KiB
C++
//
|
|
// Created by Andrew on 24/05/2023.
|
|
//
|
|
|
|
#include "header.h"
|
|
|
|
#define BINK_RETAIL MAKEINTRESOURCEW(1)
|
|
#define BINK_OEM MAKEINTRESOURCEW(2)
|
|
|
|
#define RT_BINK L"BINK"
|
|
|
|
/*
|
|
Bink resource doesn't exist
|
|
The file you selected isn't a library
|
|
Bink resource is invalid
|
|
*/
|
|
typedef struct _EC_BYTE_POINT {
|
|
CHAR x[256]; // x-coordinate of the point on the elliptic curve.
|
|
CHAR y[256]; // y-coordinate of the point on the elliptic curve.
|
|
} EC_BYTE_POINT;
|
|
|
|
typedef struct _BINKHDR {
|
|
// BINK version - not stored in the resource.
|
|
ULONG32 dwVersion;
|
|
|
|
// Original BINK header.
|
|
ULONG32 dwID;
|
|
ULONG32 dwSize;
|
|
ULONG32 dwHeaderLength;
|
|
ULONG32 dwChecksum;
|
|
ULONG32 dwDate;
|
|
ULONG32 dwKeySizeInDWORDs;
|
|
ULONG32 dwHashLength;
|
|
ULONG32 dwSignatureLength;
|
|
|
|
// Extended BINK header. (Windows Server 2003+)
|
|
ULONG32 dwAuthCodeLength;
|
|
ULONG32 dwProductIDLength;
|
|
} BINKHDR;
|
|
|
|
typedef struct _BINKDATA {
|
|
CHAR p[256]; // Finite Field order p.
|
|
CHAR a[256]; // Elliptic Curve parameter a.
|
|
CHAR b[256]; // Elliptic Curve parameter b.
|
|
|
|
EC_BYTE_POINT G; // Base point (Generator) G.
|
|
EC_BYTE_POINT K; // Public key K.
|
|
EC_BYTE_POINT I; // Inverse of the public key K.
|
|
} BINKDATA;
|
|
|
|
typedef struct _BINKEY {
|
|
BINKHDR header;
|
|
BINKDATA data;
|
|
} BINKEY;
|
|
|
|
DWORD extractBINKResource(HMODULE hLibrary, BYTE **pData) {
|
|
HRSRC hRes = FindResourceW(hLibrary, BINK_OEM, RT_BINK);
|
|
DWORD dwSize = 0;
|
|
|
|
if (hRes != NULL) {
|
|
dwSize = SizeofResource(hLibrary, hRes);
|
|
*pData = (BYTE *)LoadResource(hLibrary, hRes);
|
|
}
|
|
|
|
return dwSize;
|
|
}
|
|
|
|
BYTE hexToDecDigit(CHAR nDigit) {
|
|
nDigit = toupper(nDigit);
|
|
|
|
if (nDigit >= '0' && nDigit <= '9')
|
|
return nDigit - '0';
|
|
|
|
else
|
|
return nDigit - 'A' + 10;
|
|
}
|
|
|
|
ULONG32 byteToInteger(BYTE *pByte) {
|
|
return hexToDecDigit(pByte[0]) << 4 + hexToDecDigit(pByte[1]);
|
|
}
|
|
|
|
void reverseBytes(CONST BYTE *pBytes, ULONG32 nBytes, BYTE *pReversed) {
|
|
for (int i = nBytes - 1; i >= 0; i--) {
|
|
memcpy((BYTE *)&pBytes[i * 2], (BYTE *)&pReversed[(nBytes - i + 1) * 2], 2 * sizeof(BYTE));
|
|
}
|
|
}
|
|
|
|
ULONG32 ulToInteger(BYTE *pUL, BOOL bLittleEndian) {
|
|
BYTE pULCopy[8] = { 0 };
|
|
ULONG32 nUL = 0;
|
|
|
|
if (pUL == NULL)
|
|
return 0;
|
|
|
|
if (bLittleEndian)
|
|
reverseBytes(pUL, 4, pULCopy);
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
nUL += byteToInteger(&pULCopy[i * 2]);
|
|
}
|
|
|
|
return nUL;
|
|
}
|
|
|
|
void decodeBINKResource(BYTE *pData, ULONG32 nLength, BINKEY *pBINK) {
|
|
ULONG32 nBlockBytes = 4;
|
|
|
|
// If BINK is incomplete, return.
|
|
if (nLength < 0x170) return;
|
|
|
|
ulToInteger(pData, TRUE);
|
|
|
|
/*/ Read BINK header.
|
|
for (ULONG32 nOffset = 0; nOffset < sizeof(BINKHDR); nOffset += nBlockBytes) {
|
|
pBINK[nOffset] =
|
|
}*/
|
|
|
|
}
|
|
|
|
void base(WCHAR *pPath) {
|
|
HMODULE pIDgen = LoadLibraryExW(pPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
|
|
|
|
if (pIDgen == NULL)
|
|
return;
|
|
|
|
BYTE *pBuffer = NULL;
|
|
ULONG32 nLength = extractBINKResource(pIDgen, &pBuffer);
|
|
|
|
if (nLength == 0) {
|
|
return;
|
|
}
|
|
|
|
BINKEY pBINK = { 0 };
|
|
|
|
decodeBINKResource(pBuffer, nLength, &pBINK);
|
|
|
|
FreeLibrary(pIDgen);
|
|
} |