void MediaKeySession::UpdateKeyStatusMap() { MOZ_ASSERT(!IsClosed()); if (!mKeys->GetCDMProxy()) { return; } nsTArray<CDMCaps::KeyStatus> keyStatuses; { CDMCaps::AutoLock caps(mKeys->GetCDMProxy()->Capabilites()); caps.GetKeyStatusesForSession(mSessionId, keyStatuses); } mKeyStatusMap->Update(keyStatuses); if (EME_LOG_ENABLED()) { nsAutoCString message( nsPrintfCString("MediaKeySession[%p,'%s'] key statuses change {", this, NS_ConvertUTF16toUTF8(mSessionId).get())); for (const CDMCaps::KeyStatus& status : keyStatuses) { message.Append(nsPrintfCString(" (%s,%s)", ToBase64(status.mId).get(), MediaKeyStatusValues::strings[status.mStatus].value)); } message.Append(" }"); EME_LOG(message.get()); } }
mozilla::ipc::IPCResult GMPDecryptorParent::RecvBatchedKeyStatusChanged(const nsCString& aSessionId, InfallibleTArray<GMPKeyInformation>&& aKeyInfos) { LOGD(("GMPDecryptorParent[%p]::RecvBatchedKeyStatusChanged(sessionId='%s', KeyInfos len='%d')", this, aSessionId.get(), aKeyInfos.Length())); if (mIsOpen) { nsTArray<CDMKeyInfo> cdmKeyInfos(aKeyInfos.Length()); for (uint32_t i = 0; i < aKeyInfos.Length(); i++) { LOGD(("GMPDecryptorParent[%p]::RecvBatchedKeyStatusChanged(keyId=%s, gmp-status=%d)", this, ToBase64(aKeyInfos[i].keyId()).get(), aKeyInfos[i].status())); // If the status is kGMPUnknown, we're going to forget(remove) that key info. if (aKeyInfos[i].status() != kGMPUnknown) { auto status = ToMediaKeyStatus(aKeyInfos[i].status()); cdmKeyInfos.AppendElement(CDMKeyInfo(aKeyInfos[i].keyId(), dom::Optional<dom::MediaKeyStatus>(status))); } else { cdmKeyInfos.AppendElement(CDMKeyInfo(aKeyInfos[i].keyId())); } } mCallback->BatchedKeyStatusChanged(aSessionId, cdmKeyInfos); } return IPC_OK(); }
//================================================================== bool FileManagerAndroid::SaveFile(const char* pFileName, const U8 *pInData, size_t dataSize, const char* pMode) { DFUNCTION(); DLOG("Saving file: %s", pFileName); #if defined(ANDROID) bool prefs = isPrefsMode( pMode ); bool result = false; if (prefs) { char *base64 = ToBase64(pInData, dataSize); if (0 == base64) { DLOG("Failed to convert to base64"); return false; } DLOG("Data: %s", pInData); DLOG("Base64: %s", base64); result = ::DoWritePrefs(pFileName, base64); free(base64); } else { result = FileWrite(pFileName, pInData, dataSize); } DLOG("Returning: %s", (result)?("true"):("false")); return result; #endif return true; }
already_AddRefed<Promise> MediaKeySession::GenerateRequest(const nsAString& aInitDataType, const ArrayBufferViewOrArrayBuffer& aInitData, ErrorResult& aRv) { RefPtr<DetailedPromise> promise(MakePromise(aRv, NS_LITERAL_CSTRING("MediaKeySession.generateRequest"))); if (aRv.Failed()) { return nullptr; } if (!mUninitialized) { EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, uninitialized", this, NS_ConvertUTF16toUTF8(mSessionId).get()); promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR, NS_LITERAL_CSTRING("Session is already initialized in MediaKeySession.generateRequest()")); return promise.forget(); } mUninitialized = false; if (aInitDataType.IsEmpty()) { promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR, NS_LITERAL_CSTRING("Empty initDataType passed to MediaKeySession.generateRequest()")); EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, empty initDataType", this, NS_ConvertUTF16toUTF8(mSessionId).get()); return promise.forget(); } nsTArray<uint8_t> data; CopyArrayBufferViewOrArrayBufferData(aInitData, data); if (data.IsEmpty()) { promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR, NS_LITERAL_CSTRING("Empty initData passed to MediaKeySession.generateRequest()")); EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, empty initData", this, NS_ConvertUTF16toUTF8(mSessionId).get()); return promise.forget(); } // Convert initData to base64 for easier logging. // Note: CreateSession() Move()s the data out of the array, so we have // to copy it here. nsAutoCString base64InitData(ToBase64(data)); PromiseId pid = mKeys->StorePromise(promise); mKeys->GetCDMProxy()->CreateSession(Token(), mSessionType, pid, aInitDataType, data); EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() sent, " "promiseId=%d initData(base64)='%s' initDataType='%s'", this, NS_ConvertUTF16toUTF8(mSessionId).get(), pid, base64InitData.get(), NS_ConvertUTF16toUTF8(aInitDataType).get()); return promise.forget(); }
already_AddRefed<Promise> MediaKeySession::Update(const ArrayBufferViewOrArrayBuffer& aResponse, ErrorResult& aRv) { RefPtr<DetailedPromise> promise(MakePromise(aRv, NS_LITERAL_CSTRING("MediaKeySession.update"))); if (aRv.Failed()) { return nullptr; } if (!IsCallable()) { // If this object's callable value is false, return a promise rejected // with a new DOMException whose name is InvalidStateError. EME_LOG("MediaKeySession[%p,''] Update() called before sessionId set by CDM", this); promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR, NS_LITERAL_CSTRING("MediaKeySession.Update() called before sessionId set by CDM")); return promise.forget(); } nsTArray<uint8_t> data; if (IsClosed() || !mKeys->GetCDMProxy()) { promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR, NS_LITERAL_CSTRING("Session is closed or was not properly initialized")); EME_LOG("MediaKeySession[%p,'%s'] Update() failed, session is closed or was not properly initialised.", this, NS_ConvertUTF16toUTF8(mSessionId).get()); return promise.forget(); } CopyArrayBufferViewOrArrayBufferData(aResponse, data); if (data.IsEmpty()) { promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR, NS_LITERAL_CSTRING("Empty response buffer passed to MediaKeySession.update()")); EME_LOG("MediaKeySession[%p,'%s'] Update() failed, empty response buffer", this, NS_ConvertUTF16toUTF8(mSessionId).get()); return promise.forget(); } // Convert response to base64 for easier logging. // Note: UpdateSession() Move()s the data out of the array, so we have // to copy it here. nsAutoCString base64Response(ToBase64(data)); PromiseId pid = mKeys->StorePromise(promise); mKeys->GetCDMProxy()->UpdateSession(mSessionId, pid, data); EME_LOG("MediaKeySession[%p,'%s'] Update() sent to CDM, " "promiseId=%d Response(base64)='%s'", this, NS_ConvertUTF16toUTF8(mSessionId).get(), pid, base64Response.get()); return promise.forget(); }
bool GMPDecryptorParent::RecvForgetKeyStatus(const nsCString& aSessionId, InfallibleTArray<uint8_t>&& aKeyId) { LOGD(("GMPDecryptorParent[%p]::RecvForgetKeyStatus(sessionId='%s', keyId=%s)", this, aSessionId.get(), ToBase64(aKeyId).get())); if (mIsOpen) { mCallback->ForgetKeyStatus(aSessionId, aKeyId); } return true; }
bool GMPDecryptorParent::RecvKeyStatusChanged(const nsCString& aSessionId, InfallibleTArray<uint8_t>&& aKeyId, const GMPMediaKeyStatus& aStatus) { LOGD(("GMPDecryptorParent[%p]::RecvKeyStatusChanged(sessionId='%s', keyId=%s, status=%d)", this, aSessionId.get(), ToBase64(aKeyId).get(), aStatus)); if (mIsOpen) { mCallback->KeyStatusChanged(aSessionId, aKeyId, aStatus); } return true; }
mozilla::ipc::IPCResult GMPDecryptorParent::RecvSessionMessage(const nsCString& aSessionId, const GMPSessionMessageType& aMessageType, nsTArray<uint8_t>&& aMessage) { LOGD(("GMPDecryptorParent[%p]::RecvSessionMessage(sessionId='%s', type=%d, msg='%s')", this, aSessionId.get(), aMessageType, ToBase64(aMessage).get())); if (!mIsOpen) { NS_WARNING("Trying to use a dead GMP decrypter!"); return IPC_FAIL_NO_REASON(this); } mCallback->SessionMessage(aSessionId, ToMediaKeyMessageType(aMessageType), aMessage); return IPC_OK(); }
bool GMPDecryptorParent::RecvSessionMessage(const nsCString& aSessionId, const GMPSessionMessageType& aMessageType, nsTArray<uint8_t>&& aMessage) { LOGD(("GMPDecryptorParent[%p]::RecvSessionMessage(sessionId='%s', type=%d, msg='%s')", this, aSessionId.get(), aMessageType, ToBase64(aMessage).get())); if (!mIsOpen) { NS_WARNING("Trying to use a dead GMP decrypter!"); return false; } mCallback->SessionMessage(aSessionId, aMessageType, aMessage); return true; }
void GMPDecryptorParent::UpdateSession(uint32_t aPromiseId, const nsCString& aSessionId, const nsTArray<uint8_t>& aResponse) { LOGD(("GMPDecryptorParent[%p]::UpdateSession(sessionId='%s', promiseId=%u response='%s')", this, aSessionId.get(), aPromiseId, ToBase64(aResponse).get())); if (!mIsOpen) { NS_WARNING("Trying to use a dead GMP decrypter!"); return; } // Caller should ensure parameters passed in from JS are valid. MOZ_ASSERT(!aSessionId.IsEmpty() && !aResponse.IsEmpty()); Unused << SendUpdateSession(aPromiseId, aSessionId, aResponse); }
void MediaKeySession::DispatchKeyMessage(MediaKeyMessageType aMessageType, const nsTArray<uint8_t>& aMessage) { if (EME_LOG_ENABLED()) { EME_LOG("MediaKeySession[%p,'%s'] DispatchKeyMessage() type=%s message(base64)='%s'", this, NS_ConvertUTF16toUTF8(mSessionId).get(), MediaKeyMessageTypeValues::strings[uint32_t(aMessageType)].value, ToBase64(aMessage).get()); } RefPtr<MediaKeyMessageEvent> event( MediaKeyMessageEvent::Constructor(this, aMessageType, aMessage)); RefPtr<AsyncEventDispatcher> asyncDispatcher = new AsyncEventDispatcher(this, event); asyncDispatcher->PostDOMEvent(); }
STDMETHODIMP StdioOutputCallbacks::Output( THIS_ IN ULONG Mask, IN PCSTR Text ) { UNREFERENCED_PARAMETER(Mask); HRESULT hRes; errno_t err; size_t cbBinary; LPTSTR pszString; cbBinary = strlen(Text); if (g_OutputCbLocal) { if ((g_CmdBuffer.len + cbBinary) < (MAX_CMD-2)) { err = strcpy_s(g_CmdBuffer.buffer+g_CmdBuffer.len, MAX_CMD-g_CmdBuffer.len, Text); if (err) { g_CmdBuffer.hRes = E_FAIL; g_CmdBuffer.len = 0; } else { g_CmdBuffer.hRes = S_OK; g_CmdBuffer.len += cbBinary; } } } else { hRes = ToBase64((const byte *)Text, (unsigned int)cbBinary, &pszString); if (SUCCEEDED(hRes)) { TunnelSend("[sync] {\"type\":\"cmd\",\"msg\":\"%s\", \"base\":%llu,\"offset\":%llu}\n", pszString, g_Base, g_Offset); free(pszString); } } return S_OK; }
void GMPDecryptorParent::CreateSession(uint32_t aCreateSessionToken, uint32_t aPromiseId, const nsCString& aInitDataType, const nsTArray<uint8_t>& aInitData, GMPSessionType aSessionType) { LOGD(("GMPDecryptorParent[%p]::CreateSession(token=%u, promiseId=%u, aInitData='%s')", this, aCreateSessionToken, aPromiseId, ToBase64(aInitData).get())); if (!mIsOpen) { NS_WARNING("Trying to use a dead GMP decrypter!"); return; } // Caller should ensure parameters passed in from JS are valid. MOZ_ASSERT(!aInitDataType.IsEmpty() && !aInitData.IsEmpty()); Unused << SendCreateSession(aCreateSessionToken, aPromiseId, aInitDataType, aInitData, aSessionType); }
/* Converts a Bookmark into a text string, and writes it to the saved * bookmarks file. */ static int WriteBmLine(Bookmark *bmp, FILE *outfp, int savePassword) { char tok[256]; char pass[160]; if (fprintf(outfp, "%s", bmp->bookmarkName) < 0) return (-1) ;/*1*/ if (fprintf(outfp, ",%s", BmEscapeTok(tok, sizeof(tok), bmp->name)) < 0) return (-1) ;/*2*/ if (fprintf(outfp, ",%s", BmEscapeTok(tok, sizeof(tok), bmp->user)) < 0) return (-1) ;/*3*/ if ((bmp->pass[0] != '\0') && (savePassword == 1)) { (void) memcpy(pass, kPasswordMagic, kPasswordMagicLen); ToBase64(pass + kPasswordMagicLen, bmp->pass, strlen(bmp->pass), 1); if (fprintf(outfp, ",%s", pass) < 0) return (-1) ;/*4*/ } else { if (fprintf(outfp, ",%s", "") < 0) return (-1) ;/*4*/ } if (fprintf(outfp, ",%s", BmEscapeTok(tok, sizeof(tok), bmp->acct)) < 0) return (-1) ;/*5*/ if (fprintf(outfp, ",%s", BmEscapeTok(tok, sizeof(tok), bmp->dir)) < 0) return (-1) ;/*6*/ if (fprintf(outfp, ",%c", bmp->xferType) < 0) return (-1) ;/*7*/ if (fprintf(outfp, ",%u", (unsigned int) bmp->port) < 0) return (-1) ;/*8*/ if (fprintf(outfp, ",%lu", (unsigned long) bmp->lastCall) < 0) return (-1) ;/*9*/ if (fprintf(outfp, ",%d", bmp->hasSIZE) < 0) return (-1) ;/*10*/ if (fprintf(outfp, ",%d", bmp->hasMDTM) < 0) return (-1) ;/*11*/ if (fprintf(outfp, ",%d", bmp->hasPASV) < 0) return (-1) ;/*12*/ if (fprintf(outfp, ",%d", bmp->isUnix) < 0) return (-1) ;/*13*/ if (fprintf(outfp, ",%s", bmp->lastIP) < 0) return (-1) ;/*14*/ if (fprintf(outfp, ",%s", BmEscapeTok(tok, sizeof(tok), bmp->comment)) < 0) return (-1) ;/*15*/ if (fprintf(outfp, ",%s", "") < 0) return (-1) ;/*16*/ if (fprintf(outfp, ",%s", "") < 0) return (-1) ;/*17*/ if (fprintf(outfp, ",%s", "") < 0) return (-1) ;/*18*/ if (fprintf(outfp, ",%s", "") < 0) return (-1) ;/*19*/ if (fprintf(outfp, ",%c", bmp->xferMode) < 0) return (-1) ;/*20*/ if (fprintf(outfp, ",%d", bmp->hasUTIME) < 0) return (-1) ;/*21*/ if (fprintf(outfp, ",%s", BmEscapeTok(tok, sizeof(tok), bmp->ldir)) < 0) return (-1) ;/*22*/ if (fprintf(outfp, "\n") < 0) return (-1) ; if (fflush(outfp) < 0) return (-1); return (0); } /* WriteBmLine */
HRESULT CALLBACK modcheck(PDEBUG_CLIENT4 Client, PCSTR Args) { HRESULT hRes; DWORD cbBinary; int NbBytesRecvd = 0; LPSTR pszResString= NULL; CHAR *msg = NULL; CHAR *type; CHAR cmd[64] = {0}; BOOL bUsePdb = TRUE; INIT_API(); if(!g_Synchronized) { dprintf("[sync] please enable sync\n"); return E_FAIL; } if (!(*g_NameBuffer)) { dprintf("[sync] no module\n"); return E_FAIL; } // check args // md5 is accepted only with local debuggee if (!Args || !*Args) { bUsePdb=TRUE; } else if(strcmp("md5", Args)==0) { bUsePdb=FALSE; if (!(IsLocalDebuggee())) { dprintf("[sync] can't use md5 check with non local debuggee\n"); return E_FAIL; } } else dprintf("[sync] unknown argument, defaulting to pdb match\n"); // The debugger does not know if an IDB client // is actually connected to the dispatcher. // First disable tunnel polling for commands (happy race...) ReleasePollTimer(); // default behavior is to used !IToldYouSo command. if (bUsePdb) { type = "pdb"; _snprintf_s(cmd, 64, _TRUNCATE , "!itoldyouso %x", g_Base); // g_CommandBuffer first four bytes should contains // return value for command exec hRes=LocalCmd(Client, cmd); if (FAILED(hRes) || FAILED(*g_CommandBuffer)) { dprintf("[sync] failed to evaluate !ItoldYouSo command\n"); goto Exit; } cbBinary = (DWORD) strlen(g_CommandBuffer+4); if (cbBinary == 0) { dprintf(" ItoldYouSo return empty result\n"); goto Exit; } dprintf("%s\n", g_CommandBuffer+4); hRes=ToBase64((const byte *)g_CommandBuffer+4, cbBinary, &pszResString); if (FAILED(hRes)) { dprintf("[sync] modcheck ToBase64 failed\n"); goto Exit; } } else { type="md5"; hRes=modmd5(&pszResString); if (FAILED(hRes)) { dprintf("[sync] modcheck modmd5 failed\n"); goto Exit; } dprintf(" MD5: %s\n", pszResString); } hRes = TunnelSend("[sync]{\"type\":\"modcheck\",\"%s\":\"%s\"}\n", type, pszResString); if (FAILED(hRes)) { dprintf("[sync] modcheck send failed\n"); goto Exit; } // Let time for the IDB client to reply if it exists Sleep(150); // Poll tunnel hRes=TunnelPoll(&NbBytesRecvd, &msg); if (FAILED(hRes)) { dprintf("[sync] modcheck poll failed\n"); goto Exit; } else { if ((NbBytesRecvd>0) & (msg != NULL)) dprintf("%s\n", msg); else dprintf(" -> no reply, make sure an idb is enabled first\n"); } Exit: // Re-enable tunnel polling CreatePollTimer(); if (pszResString) free(pszResString); if (msg) free(msg); return hRes; }
// Generates a license request based on the initData. A message of type // "license-request" or "individualization-request" will always be queued // if the algorithm succeeds and the promise is resolved. already_AddRefed<Promise> MediaKeySession::GenerateRequest(const nsAString& aInitDataType, const ArrayBufferViewOrArrayBuffer& aInitData, ErrorResult& aRv) { RefPtr<DetailedPromise> promise(MakePromise(aRv, NS_LITERAL_CSTRING("MediaKeySession.generateRequest"))); if (aRv.Failed()) { return nullptr; } // If this object is closed, return a promise rejected with an InvalidStateError. if (IsClosed()) { EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, closed", this, NS_ConvertUTF16toUTF8(mSessionId).get()); promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR, NS_LITERAL_CSTRING("Session is closed in MediaKeySession.generateRequest()")); return promise.forget(); } // If this object's uninitialized value is false, return a promise rejected // with an InvalidStateError. if (!mUninitialized) { EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, uninitialized", this, NS_ConvertUTF16toUTF8(mSessionId).get()); promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR, NS_LITERAL_CSTRING("Session is already initialized in MediaKeySession.generateRequest()")); return promise.forget(); } // Let this object's uninitialized value be false. mUninitialized = false; // If initDataType is the empty string, return a promise rejected // with a newly created TypeError. if (aInitDataType.IsEmpty()) { promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR, NS_LITERAL_CSTRING("Empty initDataType passed to MediaKeySession.generateRequest()")); EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, empty initDataType", this, NS_ConvertUTF16toUTF8(mSessionId).get()); return promise.forget(); } // If initData is an empty array, return a promise rejected with // a newly created TypeError. nsTArray<uint8_t> data; CopyArrayBufferViewOrArrayBufferData(aInitData, data); if (data.IsEmpty()) { promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR, NS_LITERAL_CSTRING("Empty initData passed to MediaKeySession.generateRequest()")); EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, empty initData", this, NS_ConvertUTF16toUTF8(mSessionId).get()); return promise.forget(); } // If the Key System implementation represented by this object's // cdm implementation value does not support initDataType as an // Initialization Data Type, return a promise rejected with a // NotSupportedError. String comparison is case-sensitive. if (!MediaKeySystemAccess::KeySystemSupportsInitDataType(mKeySystem, aInitDataType)) { promise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR, NS_LITERAL_CSTRING("Unsupported initDataType passed to MediaKeySession.generateRequest()")); EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, unsupported initDataType", this, NS_ConvertUTF16toUTF8(mSessionId).get()); return promise.forget(); } // Let init data be a copy of the contents of the initData parameter. // Note: Handled by the CopyArrayBufferViewOrArrayBufferData call above. // Let session type be this object's session type. // Let promise be a new promise. // Run the following steps in parallel: // If the init data is not valid for initDataType, reject promise with // a newly created TypeError. if (!ValidateInitData(data, aInitDataType)) { // If the preceding step failed, reject promise with a newly created TypeError. promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR, NS_LITERAL_CSTRING("initData sanitization failed in MediaKeySession.generateRequest()")); EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() initData sanitization failed", this, NS_ConvertUTF16toUTF8(mSessionId).get()); return promise.forget(); } // Let sanitized init data be a validated and sanitized version of init data. // If sanitized init data is empty, reject promise with a NotSupportedError. // Note: Remaining steps of generateRequest method continue in CDM. Telemetry::Accumulate(Telemetry::VIDEO_CDM_GENERATE_REQUEST_CALLED, ToCDMTypeTelemetryEnum(mKeySystem)); // Convert initData to base64 for easier logging. // Note: CreateSession() Move()s the data out of the array, so we have // to copy it here. nsAutoCString base64InitData(ToBase64(data)); PromiseId pid = mKeys->StorePromise(promise); mKeys->ConnectPendingPromiseIdWithToken(pid, Token()); mKeys->GetCDMProxy()->CreateSession(Token(), mSessionType, pid, aInitDataType, data); EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() sent, " "promiseId=%d initData(base64)='%s' initDataType='%s'", this, NS_ConvertUTF16toUTF8(mSessionId).get(), pid, base64InitData.get(), NS_ConvertUTF16toUTF8(aInitDataType).get()); return promise.forget(); }
HRESULT CALLBACK bpcmds(PDEBUG_CLIENT4 Client, PCSTR Args) { HRESULT hRes=S_OK; char *msg, *decoded, *query; LPSTR pszString; int NbBytesRecvd; size_t cbBinary; INIT_API(); #if VERBOSE >= 2 dprintf("[sync] !bpcmds called\n"); #endif if(!g_Synchronized) { dprintf("[sync] please enable sync\n"); return E_FAIL; } if (!Args || !*Args){ msg = "query"; } else { msg = (char *)Args; } if ((strncmp("load", msg, 4)==0) || (strncmp("query", msg, 5)==0)) { dprintf("[sync] query idb for bpcmds\n"); hRes=TunnelSend("[sync]{\"type\":\"bps_get\"}\n"); } else if(strncmp("save", msg, 4)==0) { dprintf("[sync] dumping bpcmds to idb\n"); hRes=LocalCmd(Client, ".bpcmds"); // g_CommandBuffer first four bytes should contains // return value for command exec if (FAILED(hRes) || FAILED(*g_CommandBuffer)) { dprintf("[sync] failed to evaluate .bpcmds command\n"); return E_FAIL; } cbBinary = strlen(g_CommandBuffer+4); dprintf("%s\n", g_CommandBuffer); hRes = ToBase64((const byte *)g_CommandBuffer+4, (unsigned int)cbBinary, &pszString); if (SUCCEEDED(hRes)) { hRes = TunnelSend("[sync]{\"type\":\"bps_set\",\"msg\":\"%s\"}\n", pszString); free(pszString); } } else { dprintf("[sync] usage !bpcmds <||query|save|load|\n"); return E_FAIL; } // Check if we failed to query the idb client if (FAILED(hRes)){ dprintf("[sync] !bpcmds failed\n"); return hRes; } // Get result from idb client hRes=TunnelReceive(&NbBytesRecvd, &query); if (!(SUCCEEDED(hRes) & (NbBytesRecvd>0) & (query != NULL))) { dprintf("[sync] !bpcmds failed\n"); return hRes; } // Handle result if(strncmp("load", msg, 4)==0) { hRes = FromBase64(query, (BYTE **)(&decoded)); if (SUCCEEDED(hRes)) { hRes = ExecCmdList(decoded); free(decoded); } } else if(strncmp("query", msg, 4)==0) { hRes = FromBase64(query, (BYTE **)(&decoded)); if (SUCCEEDED(hRes)) { dprintf("[sync] idb's saved bpcmds:\n %s\n", decoded); free(decoded); } } else { dprintf("%s\n", query); } free(query); return hRes; }