📄 msdrm.c
字号:
1) * sizeof(wchar_t));
if (tmp == NULL)
error_exit
("Memory allocation failed in get_element (2)");
memcpy(tmp, realstart,
(end - realstart) * sizeof(wchar_t));
tmp[end - realstart] = L'\0';
rval = tmp;
}
}
exit:
free(tmptag);
return rval;
}
/*
* getDRMDataPath allocates extra room on the end (20 wchars) for
* appending a filename
*/
static wchar_t *getDRMDataPath()
{
HKEY key_drm;
long stat;
DWORD dtype, dlen;
wchar_t *buff;
stat =
RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\DRM", 0,
KEY_READ, &key_drm);
if (FAILED(stat))
return NULL;
stat =
RegQueryValueEx(key_drm, "DataPath", NULL, NULL, NULL, &dlen);
if (FAILED(stat))
return NULL;
if ((buff =
(wchar_t *) malloc(dlen + 20 * sizeof(wchar_t))) == NULL)
error_exit("Memory allocation failed in getDRMDataPath");
stat =
RegQueryValueEx(key_drm, "DataPath", NULL, &dtype,
(uchar *) buff, &dlen);
if (FAILED(stat)) {
free(buff);
return NULL;
}
RegCloseKey(key_drm);
return buff;
}
int fileExistsA(char *fname)
{
return (GetFileAttributes(fname) != -1);
}
int fileExistsW(wchar_t * fname)
{
char buffer[MAX_PATH];
int len;
len = wcslen(fname);
if (WideCharToMultiByte
(CP_ACP, 0, fname, len + 1, buffer, MAX_PATH, NULL, NULL) == 0)
return 0;
return fileExistsA(buffer);
}
void getKSFilename(wchar_t * ksname, char *libname)
{
wchar_t *basepath = getDRMDataPath();
wchar_t currks[MAX_PATH], lastks[MAX_PATH];
char abasepath[MAX_PATH];
char currlib[MAX_PATH], lastlib[MAX_PATH];
int fnum;
if (basepath != NULL) {
WideCharToMultiByte(CP_ACP, 0, basepath,
wcslen(basepath) + 1, abasepath,
MAX_PATH, NULL, NULL);
swprintf(lastks, L"%s\\v2ks.bla", basepath);
swprintf(currks, L"%s\\v2ksndv.bla", basepath);
sprintf(lastlib, "BlackBox.dll");
sprintf(currlib, "%s\\IndivBox.key", abasepath);
fnum = 1;
while (fileExistsW(currks) && (fileExistsA(currlib))) {
fnum++;
wcscpy(lastks, currks);
swprintf(currks, L"%s\\v2ks%03x.bla", basepath,
fnum);
strcpy(lastlib, currlib);
sprintf(currlib, "%s\\Indiv%03x.key", basepath,
fnum);
}
wcscpy(ksname, lastks);
strcpy(libname, lastlib);
free(basepath);
}
}
static int getkeypairs()
{
HMODULE mylib;
int rval;
BBOXOBJ *bbobj;
char errmsg[100];
wchar_t KSFilename[MAX_PATH];
char BBoxLib[MAX_PATH];
int i;
getKSFilename(KSFilename, BBoxLib);
if (globalinfo.verbose) {
fprintf(stderr, "BlackBox library to use: %s\n", BBoxLib);
fprintf(stderr, "Keystore to use: ");
printwcs(KSFilename);
fprintf(stderr, "\n");
}
mylib = LoadLibraryA(BBoxLib);
if (mylib == NULL) {
DWORD err = GetLastError();
sprintf(errmsg, "Failed loading library. Err code %08x",
err);
error_exit(errmsg);
} else {
typedef int (WINAPI * createfn) (BBOXOBJ **,
unsigned short *);
createfn create =
(createfn) GetProcAddress(mylib,
"IBlackBox_CreateInstance2");
if (create == NULL)
error_exit("Failed finding proc address.");
else {
rval = (*create) (&bbobj, KSFilename);
if (bbobj == NULL) {
sprintf(errmsg,
"Failed to create a black box object (err code %08x)\n",
rval);
error_exit(errmsg);
}
if (globalinfo.verbose) {
fprintf(stderr,
"Created BlackBox instance - extracting key pairs\n");
}
memcpy(&keypair[0].private, &bbobj->ecprivkey, 20);
memcpy(&keypair[0].public, bbobj->clientid, 40);
numkeypairs = bbobj->numkeypairs + 1;
for (i = 0; i < bbobj->numkeypairs; i++) {
memcpy(&keypair[i + 1].public,
bbobj->keypairs + 60 * i, 40);
memcpy(&keypair[i + 1].private,
bbobj->keypairs + 60 * i + 40, 20);
}
if (globalinfo.verbose) {
fprintf(stderr, "\n");
for (i = 0; i < numkeypairs; i++) {
fprintf(stderr,
"Public key %d x: ",
i + 1);
printMSBN(&keypair[i].public.x);
fprintf(stderr,
"\nPublic key %d y: ",
i + 1);
printMSBN(&keypair[i].public.y);
fprintf(stderr,
"\nPrivate key %d: ",
i + 1);
printMSBN(&keypair[i].private);
fprintf(stderr, "\n\n");
}
}
}
FreeLibrary(mylib);
}
return 0;
}
static CONTKEY *checkLicense(wchar_t * license)
{
wchar_t *ebits = NULL;
wchar_t *pubkey = NULL;
wchar_t *value = NULL;
MS_BN *privkey = NULL;
CONTKEY *ckey = NULL;
MS_BN *thispubkey;
int i;
if ((ebits = get_element(L"ENABLINGBITS", license)) == NULL)
error_exit("No ENABLINGBITS element in license!");
if ((pubkey = get_element(L"PUBKEY", ebits)) == NULL)
error_exit("No PUBKEY element in license!");
if ((value = get_element(L"VALUE", ebits)) == NULL)
error_exit("No VALUE element in license!");
MS_Base64Decode(pubkey, (char **) &thispubkey);
if (globalinfo.verbose) {
fprintf(stderr, "Checking license with PUBKEY ");
printMSBN(thispubkey);
fprintf(stderr, "\n");
}
for (i = 0; i < numkeypairs; i++) {
if (memcmp(thispubkey, (char *) &keypair[i].public, 40) ==
0) {
privkey = &keypair[i].private;
break;
}
}
if (privkey != NULL) {
if ((ckey = malloc(sizeof(CONTKEY))) == NULL)
error_exit
("Memory allocation failed in checkLicense");
if (globalinfo.verbose) {
fprintf(stderr,
"Matched public key! Proceeding...\n");
}
MSDRM_setup(privkey, value, ckey);
}
free(thispubkey);
free(value);
free(pubkey);
free(ebits);
return ckey;
}
static CONTKEY *getContKey(wchar_t * licFile, wchar_t * kid)
{
HRESULT hr;
IStorage *pStg = NULL, *pStgChild = NULL;
IStream *pStrmLicense;
IEnumSTATSTG *penum = NULL;
STATSTG statstg, statstrm;
wchar_t *license = NULL;
unsigned long statLen, reallyRead;
CONTKEY *ckey;
hr = StgOpenStorage(licFile, NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, 0,
&pStg);
if (FAILED(hr))
error_exit("Couldn't open license file!");
hr = pStg->lpVtbl->OpenStorage(pStg, kid, NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE,
NULL, 0, &pStgChild);
if (FAILED(hr))
return NULL;
hr = pStgChild->lpVtbl->EnumElements(pStgChild, 0, NULL, 0,
&penum);
if (FAILED(hr))
error_exit("Couldn't EnumElements in storage.");
memset(&statstg, 0, sizeof(statstg));
hr = penum->lpVtbl->Next(penum, 1, &statstg, 0);
while (S_OK == hr) {
hr = pStgChild->lpVtbl->OpenStream(pStgChild,
statstg.pwcsName, NULL,
STGM_READ |
STGM_SHARE_EXCLUSIVE, 0,
&pStrmLicense);
if (FAILED(hr))
error_exit("Couldn't open license!");
hr = pStrmLicense->lpVtbl->Stat(pStrmLicense, &statstrm,
0);
statLen = (unsigned long) statstrm.cbSize.QuadPart / 2;
if ((license =
(wchar_t *) malloc(2 * (statLen + 1))) == NULL)
error_exit
("Memory allocation failed in getContKey.");
hr = pStrmLicense->lpVtbl->Read(pStrmLicense, license,
2 * statLen, &reallyRead);
if ((FAILED(hr)) || (reallyRead != 2 * statLen))
error_exit("License read failed.");
license[statLen] = 0;
pStrmLicense->lpVtbl->Release(pStrmLicense);
if ((ckey = checkLicense(license + 1)) != NULL) {
free(license);
pStgChild->lpVtbl->Release(pStgChild);
pStg->lpVtbl->Release(pStg);
return ckey;
}
free(license);
hr = penum->lpVtbl->Next(penum, 1, &statstg, 0);
}
return NULL;
}
static void convertKID(wchar_t * kid)
{
while (*kid != L'\0') {
if (*kid == L'/')
*kid = L'@';
else if (*kid == L'!')
*kid = L'%';
kid++;
}
}
CONTKEY *MSDRM_init(wchar_t * kid)
{
CONTKEY *ckey;
wchar_t *licfile;
licfile = getDRMDataPath();
if (licfile == NULL)
error_exit("Couldn't get DRM data path from registry.");
wcscat(licfile, L"\\drmv2.lic");
if (globalinfo.verbose) {
fprintf(stderr, "License file full path: ");
printwcs(licfile);
fprintf(stderr, "\n");
}
getkeypairs();
convertKID(kid);
ckey = getContKey(licfile, kid);
if (ckey == NULL)
error_exit
("Couldn't find a valid license for this content.");
free(licfile);
return ckey;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -