void CALLBACK DebugExtensionNotify(ULONG Notify, ULONG64 Argument) { UNREFERENCED_PARAMETER(Argument); HRESULT hRes=S_OK; BOOL bIgnoreEvent = false; switch(Notify){ case DEBUG_NOTIFY_SESSION_ACTIVE: #if VERBOSE >= 2 dprintf("[sync] DebugExtensionNotify: A debugging session is active. The session may not necessarily be suspended.\n"); #endif break; case DEBUG_NOTIFY_SESSION_INACTIVE: #if VERBOSE >= 2 dprintf("[sync] DebugExtensionNotify: No debugging session is active.\n"); #endif break; case DEBUG_NOTIFY_SESSION_ACCESSIBLE: #if VERBOSE >= 2 dprintf("[sync] DebugExtensionNotify: The debugging session has suspended and is now accessible.\n"); #endif if(SUCCEEDED(TunnelIsUp())) { hRes = EventFilterCb(&bIgnoreEvent); if(SUCCEEDED(hRes) && bIgnoreEvent) break; UpdateState(); CreatePollTimer(); } break; case DEBUG_NOTIFY_SESSION_INACCESSIBLE: #if VERBOSE >= 2 dprintf("[sync] DebugExtensionNotify: The debugging session has started running and is now inaccessible.\n"); #endif ReleasePollTimer(); break; default: #if VERBOSE >= 2 dprintf("[sync] DebugExtensionNotify: Unknown Notify reason (%x).\n", Notify); #endif break; } return; }
extern "C" __declspec(dllexport) void CBPAUSEDEBUG(CBTYPE cbType, PLUG_CB_PAUSEDEBUG* info) { #if VERBOSE >= 2 _plugin_logputs("[sync] debugging paused!"); #endif if (SUCCEEDED(TunnelIsUp())) { UpdateState(); CreatePollTimer(); } }
HRESULT sync(PSTR Args) { HRESULT hRes = S_OK; // Reset global state g_Base = NULL; g_Offset = NULL; if (g_Synchronized) { _plugin_logputs("[sync] sync update\n"); UpdateState(); goto Exit; } if (FAILED(hRes = TunnelCreate(g_DefaultHost, g_DefaultPort))) { _plugin_logputs("[sync] sync failed\n"); goto Exit; } _plugin_logputs("[sync] probing sync\n"); hRes = TunnelSend("[notice]{\"type\":\"new_dbg\",\"msg\":\"dbg connect - x64_dbg\",\"dialect\":\"x64_dbg\"}\n"); if (FAILED(hRes)) { _plugin_logputs("[sync] sync aborted\n"); goto Exit; } _plugin_logprintf("[sync] sync is now enabled with host %s\n", g_DefaultHost); UpdateState(); CreatePollTimer(); Exit: return hRes; }
HRESULT CALLBACK sync(PDEBUG_CLIENT4 Client, PCSTR Args) { HRESULT hRes=S_OK; PCSTR Host; PSTR pszId=NULL; INIT_API(); // Reset global state g_Base = NULL; g_Offset = NULL; #if VERBOSE >= 2 dprintf("[sync] sync function called\n"); #endif if(g_Synchronized) { dprintf("[sync] sync update\n"); UpdateState(); goto exit; } if (!Args || !*Args) { dprintf("[sync] No argument found, using default host (%s:%s)\n", g_DefaultHost, g_DefaultPort); Host=g_DefaultHost; }else{ Host=Args; } if(FAILED(hRes=TunnelCreate(Host, g_DefaultPort))) { dprintf("[sync] sync failed\n"); goto exit; } dprintf("[sync] probing sync\n"); if(FAILED(hRes=Identity(&pszId))) { dprintf("[sync] get identity failed\n"); goto exit; } hRes=TunnelSend("[notice]{\"type\":\"new_dbg\",\"msg\":\"dbg connect - %s\"}\n", pszId); if(SUCCEEDED(hRes)) { dprintf("[sync] sync is now enabled with host %s\n", Host); UpdateState(); CreatePollTimer(); } else { dprintf("[sync] sync aborted\n"); } exit: if(!(pszId==NULL)) free(pszId); return hRes; }
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; }