Esempio n. 1
0
// Update state and send info to client: eip module's base address, offset, name
HRESULT
UpdateState()
{
	bool bRes = FALSE;
	HRESULT hRes = E_FAIL;
	DWORD dwRes = 0;
	ULONG64 PrevBase = g_Base;
	ULONG NameSize = 0;
	HANDLE hProcess;

	g_Offset = GetContextData(UE_CIP);

	bRes = DbgGetModuleAt((duint)g_Offset, g_NameBuffer);
	if (!bRes)
	{
		_plugin_logprintf("[sync] UpdateState: no module at %p...\n", g_Offset);
		return hRes;
	}

	g_Base = DbgModBaseFromName(g_NameBuffer);
	if (!g_Base)
	{
		_plugin_logputs("[sync] UpdateState: could not get module base...");
		return hRes;
	}

	// Check if we are in a new module
	if ((g_Base != PrevBase) & g_SyncAuto)
	{
		hProcess = ((PROCESS_INFORMATION*)TitanGetProcessInformation())->hProcess;

		dwRes = GetModuleBaseNameA(hProcess, (HMODULE)g_Base, g_NameBuffer, MAX_MODULE_SIZE);
		if (dwRes==0)
		{
			_plugin_logputs("[sync] could not get module base name...");
			return hRes;
		}

#if VERBOSE >= 2
		_plugin_logprintf("[sync] UpdateState: module : \"%s\"\n", g_NameBuffer);
#endif

		hRes = TunnelSend("[notice]{\"type\":\"module\",\"path\":\"%s\"}\n", g_NameBuffer);
		if (FAILED(hRes)){

			return hRes;
		}
	}

	hRes = TunnelSend("[sync]{\"type\":\"loc\",\"base\":%llu,\"offset\":%llu}\n", g_Base, g_Offset);

	return hRes;
}
Esempio n. 2
0
// Update state and send info to client: eip module's base address, offset, name
HRESULT
UpdateState()
{
    HRESULT hRes;
    ULONG64 PrevBase = g_Base;
    ULONG NameSize=0;

    /*
    msdn: GetInstructionOffset method returns the location of
    the current thread's current instruction.
    */
    hRes=g_ExtRegisters->GetInstructionOffset(&g_Offset);
    #if VERBOSE >= 2
    if(SUCCEEDED(hRes))
        dprintf("[sync] GetInstructionOffset 0x%x\n", g_Offset);
    #endif

    /*
    msdn: GetModuleByOffset method searches through the target's modules for one
    whose memory allocation includes the specified location.
    */
    hRes=g_ExtSymbols->GetModuleByOffset(g_Offset, 0, NULL, &g_Base);
    #if VERBOSE >= 2
    if(SUCCEEDED(hRes))
        dprintf("[sync] base address 0x%x\n", g_Base);
    #endif

    // Check if we are in a new module
    if ((g_Base != PrevBase) & g_SyncAuto)
    {
        /*
        Update module name stored in g_NameBuffer
        msdn: GetModuleNameString  method returns the name of the specified module.
        */
        hRes=g_ExtSymbols2->GetModuleNameString(DEBUG_MODNAME_LOADED_IMAGE, DEBUG_ANY_ID, g_Base, g_NameBuffer, MAX_NAME, &NameSize);
        if(SUCCEEDED(hRes) & (NameSize>0) & (((char) *g_NameBuffer)!=0))
        {
            #if VERBOSE >= 2
            dprintf("[sync] DEBUG_MODNAME_LOADED_IMAGE: \"%s\"\n", g_NameBuffer);
            #endif

            hRes=TunnelSend("[notice]{\"type\":\"module\",\"path\":\"%s\"}\n", g_NameBuffer);
            if(FAILED(hRes))
                return hRes;
        }
    }

    hRes=TunnelSend("[sync]{\"type\":\"loc\",\"base\":%llu,\"offset\":%llu}\n", g_Base, g_Offset);
    return hRes;
}
Esempio n. 3
0
HRESULT
CALLBACK
idbn(PDEBUG_CLIENT4 Client, PCSTR Args)
{
    HRESULT hRes=S_OK;
    int NbBytesRecvd;
    char * msg = NULL;
    INIT_API();

    if (!Args || !*Args) {
        dprintf("[sync] !idbn <idb num>\n");
        return E_FAIL;
    }

    #if VERBOSE >= 2
    dprintf("[sync] !idbn called\n");
    #endif

    hRes=TunnelSend("[notice]{\"type\":\"idb_n\",\"idb\":\"%s\"}\n", Args);
    if (FAILED(hRes)){
        dprintf("[sync] !idblist failed\n");
        return hRes;
    }

    hRes=TunnelReceive(&NbBytesRecvd, &msg);
    if (SUCCEEDED(hRes) & (NbBytesRecvd>0) & (msg != NULL)){
        dprintf("%s\n", msg);
        free(msg);
    }

    return hRes;
}
Esempio n. 4
0
HRESULT
CALLBACK
idblist(PDEBUG_CLIENT4 Client, PCSTR Args)
{
    HRESULT hRes=S_OK;
    UNREFERENCED_PARAMETER(Args);
    INIT_API();

    int NbBytesRecvd;
    char * msg = NULL;

    #if VERBOSE >= 2
    dprintf("[sync] !idblist called\n");
    #endif

    hRes=TunnelSend("[notice]{\"type\":\"idb_list\"}\n");
    if (FAILED(hRes)){
        dprintf("[sync] !idblist failed\n");
        return hRes;
    }

    hRes=TunnelReceive(&NbBytesRecvd, &msg);
    if (SUCCEEDED(hRes) & (NbBytesRecvd>0) & (msg != NULL)){
        dprintf("%s\n", msg);
        free(msg);
    }

    return hRes;
}
Esempio n. 5
0
HRESULT
CALLBACK
syncmodauto(PDEBUG_CLIENT4 Client, PCSTR Args)
{
    HRESULT hRes=S_OK;
    char * msg;
    INIT_API();

    #if VERBOSE >= 2
    dprintf("[sync] !syncmodauto called\n");
    #endif

    if (!Args || !*Args)
        goto syncmod_arg_fail;

    if(strcmp("on", Args)==0)
    {
        msg = (char *)Args;
        g_SyncAuto = true;
    }
    else if (strcmp("off", Args)==0)
    {
        msg = (char *)Args;
        g_SyncAuto = false;
    }
    else
        goto syncmod_arg_fail;

    hRes=TunnelSend("[notice]{\"type\":\"sync_mode\",\"auto\":\"%s\"}\n", msg);
    return hRes;

syncmod_arg_fail:
    dprintf("[sync] usage !syncmodauto <on|off>\n");
    return E_FAIL;
}
Esempio n. 6
0
HRESULT
CALLBACK
jmpraw(PDEBUG_CLIENT4 Client, PCSTR Args)
{
    HRESULT hRes;
    ULONG64 Offset =0;
    ULONG RemainderIndex;
    DEBUG_VALUE DebugValue = {};
    INIT_API();

    if (!Args || !*Args)
    {
        dprintf("[sync] !jumpraw <expression>\n");
        return E_FAIL;
    }

    /*
    msdn: Evaluate method evaluates an expression, returning the result.
    */
    hRes=g_ExtControl->Evaluate(Args, DEBUG_VALUE_INT64, &DebugValue, &RemainderIndex);
    if(FAILED(hRes))
    {
        dprintf("[sync] jumpraw: failed to evaluate expression\n");
        return E_FAIL;
    }

    Offset = (ULONG64)DebugValue.I64;

    hRes=TunnelSend("[sync]{\"type\":\"loc\",\"offset\":%llu}\n", Offset);

    return hRes;
}
Esempio n. 7
0
HRESULT TunnelClose()
{
    HRESULT hRes=S_OK;
    int iResult;

    if(SUCCEEDED(TunnelIsUp()))
    {
        hRes=TunnelSend("[notice]{\"type\":\"dbg_quit\",\"msg\":\"dbg disconnected\"}\n");
        if(FAILED(hRes))
            return hRes;
    }
    
    if(!(g_Sock == INVALID_SOCKET)){
        iResult = closesocket(g_Sock);
        g_Sock = INVALID_SOCKET;

        if (iResult == SOCKET_ERROR)
            dprintf("[sync] closesocket failed with error %d\n", WSAGetLastError());
    }

    dprintf("[sync] sync is off\n");
    g_Synchronized=FALSE;
    WSACleanup();
    return hRes;
}
Esempio n. 8
0
HRESULT
CALLBACK
bc(PDEBUG_CLIENT4 Client, PCSTR Args)
{
    HRESULT hRes=S_OK;
    ULONG DwRGB = 0;
    ULONG RemainderIndex;
    DEBUG_VALUE DebugValue = {};
    char * msg;
    char * rgb_msg[64] = {0};
    INIT_API();

    #if VERBOSE >= 2
    dprintf("[sync] !bc called\n");
    #endif

    if (!Args || !*Args)
    {
        msg = "oneshot";
    }
    else if (strcmp("on", Args) == 0)
    {
        msg = (char *)Args;
    }
    else if (strcmp("off", Args) == 0)
    {
        msg = (char *)Args;
    }

    else if (strncmp("set ", Args, 4) == 0)
    {
        *((char *)Args+3) = 0;
        hRes=g_ExtControl->Evaluate((char *) (Args+4), DEBUG_VALUE_INT32, &DebugValue, &RemainderIndex);
        if(FAILED(hRes))
        {
            dprintf("[sync] failed to evaluate RGB code\n");
            return E_FAIL;
        }

        DwRGB = (ULONG)DebugValue.I32;
        _snprintf_s((char *) rgb_msg, 64, _TRUNCATE , "%s\", \"rgb\":%lu, \"reserved\":\"", Args, DwRGB);
        msg = (char *)rgb_msg;
    }
    else
    {
        dprintf("[sync] usage !bc <|||on|off|set 0xBBGGRR> >\n");
        return E_FAIL;
    }

    hRes=TunnelSend("[sync]{\"type\":\"bc\",\"msg\":\"%s\",\"base\":%llu,\"offset\":%llu}\n", msg, g_Base, g_Offset);
    return hRes;
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
HRESULT
CALLBACK
fcmt(PDEBUG_CLIENT4 Client, PCSTR Args)
{
    HRESULT hRes=S_OK;
    INIT_API();

    #if VERBOSE >= 2
    dprintf("[sync] !fcmt called\n");
    #endif

    if (!Args || !*Args) {
        Args = "";
    }

    hRes=TunnelSend("[sync]{\"type\":\"fcmt\",\"msg\":\"%s\",\"base\":%llu,\"offset\":%llu}\n", Args, g_Base, g_Offset);

    return hRes;
}
Esempio n. 11
0
HRESULT
CALLBACK
lbl(PDEBUG_CLIENT4 Client, PCSTR Args)
{
    HRESULT hRes=S_OK;
    INIT_API();

    #if VERBOSE >= 2
    dprintf("[sync] !lbl called\n");
    #endif

    if (!Args || !*Args) {
        dprintf("[sync] !lbl <comment to add>\n");
        return E_FAIL;
    }

    hRes=TunnelSend("[sync]{\"type\":\"lbl\",\"msg\":\"%s\",\"base\":%llu,\"offset\":%llu}\n", Args, g_Base, g_Offset);

    return hRes;
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
HRESULT
CALLBACK
jmpto(PDEBUG_CLIENT4 Client, PCSTR Args)
{
    HRESULT hRes;
    ULONG64 Base, Offset =0;
    ULONG NameSize=0;
    ULONG RemainderIndex;
    DEBUG_VALUE DebugValue = {};
    INIT_API();

    if (!Args || !*Args)
    {
        dprintf("[sync] !jumpto <expression>\n");
        return E_FAIL;
    }

    /*
    msdn: Evaluate method evaluates an expression, returning the result.
    */
    hRes=g_ExtControl->Evaluate(Args, DEBUG_VALUE_INT64, &DebugValue, &RemainderIndex);
    if(FAILED(hRes))
    {
        dprintf("[sync] jumpto: failed to evaluate expression\n");
        return E_FAIL;
    }

    Offset = (ULONG64)DebugValue.I64;

    /*
    msdn: GetModuleByOffset method searches through the target's modules for one
    whose memory allocation includes the specified location.
    */
    hRes=g_ExtSymbols->GetModuleByOffset(Offset, 0, NULL, &Base);
    if(FAILED(hRes))
    {
        dprintf("[sync] jumpto: failed to get module base for address 0x%x\n", Base);
        return E_FAIL;
    }

    /*
    Update module name stored in g_NameBuffer
    msdn: GetModuleNameString  method returns the name of the specified module.
    */
    hRes=g_ExtSymbols2->GetModuleNameString(DEBUG_MODNAME_LOADED_IMAGE, DEBUG_ANY_ID, Base, g_NameBuffer, MAX_NAME, &NameSize);
    if(!(SUCCEEDED(hRes) & (NameSize>0) & (((char) *g_NameBuffer)!=0)))
    {
        dprintf("[sync] jumpto: failed to get module name for target address\n");
        return E_FAIL;
    }

    // Check if we are in a new module
    if(g_Base != Base)
    {
        // Update base address of current active module
        g_Base = Base;

        hRes=TunnelSend("[notice]{\"type\":\"module\",\"path\":\"%s\"}\n", g_NameBuffer);
        if(FAILED(hRes))
            return hRes;
    }

    hRes=TunnelSend("[sync]{\"type\":\"loc\",\"base\":%llu,\"offset\":%llu}\n", Base, Offset);

    return hRes;
}
Esempio n. 14
0
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;
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
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;
}