예제 #1
0
/* static */
BOOL
wxDbgHelpDLL::CallSymEnumSymbols(HANDLE hProcess,
                                 ULONG64 baseOfDll,
                                 wxPSYM_ENUMERATESYMBOLS_CALLBACK callback,
                                 const PVOID callbackParam)
{
#ifdef UNICODE
    if ( SymEnumSymbolsW )
    {
        if ( SymEnumSymbolsW(hProcess, baseOfDll, NULL, callback, callbackParam) )
            return TRUE;
    }

    if ( SymEnumSymbols )
    {
        wxEnumSymbolsCallbackBridge br(callback, callbackParam);

        if ( SymEnumSymbols(hProcess, baseOfDll, NULL, wxEnumSymbolsCallback, &br) )
            return TRUE;
    }
#else // !UNICODE
    if ( SymEnumSymbols )
    {
        if ( SymEnumSymbols(hProcess, baseOfDll, NULL, callback, callbackParam) )
            return TRUE;
    }
#endif // UNICODE/!UNICODE

    return FALSE;
}
예제 #2
0
int Psymbol_iter_by_addr(struct ps_prochandle *P, const char *object_name, int which, int mask, proc_sym_f *func, void *cd)
{
    prmap_t *map ;
    struct lookup_uc uc;
    proc_mod_t *mod = findmodulebyname(P, object_name);
    /* this fails miserable - dtrace -n pid$target:user32:N*:entry pid$target:M*::entry -c exe
      the second probe spec will be ignored */
    if (mod == NULL || mod->loaded_order < P->dll_load_order)
        return 0;

    if (strcmp("a.out", object_name) == 0)
        map = Plmid_to_map(P, 0, P->exe_module->name);
    else
        map = Plmid_to_map(P, 0, object_name);

    if (map == NULL) {
        return -1;
    }

    uc.f = func;
    uc.cd = cd;
    uc.ps = P;
    uc.count = 0;

    if (SymEnumSymbols(P->phandle, mod->imgbase, NULL, SymEnumSymbolsProc, &uc) == FALSE) {
        dprintf("Psymbol_iter_by_addr: SymEnumSymbols failed %s: %x\n", object_name, GetLastError());
        return -1;
    }

    if (uc.count != 0)
        return 0;

    return dw_iter_by_addr(P, object_name, which, mask, func, cd);
}
예제 #3
0
    void FunctionResolver::resolveParameters(const ULONG64& functionAddress, const ULONG64& modBase, const ULONG& typeIndex, std::vector<FunctionParameter>& resolvedParameters)
    {
        IMAGEHLP_STACK_FRAME sf;

        sf.InstructionOffset = functionAddress;

        if (!SymSetContext(this->m_hProcess, &sf, 0))
        {
            throw;
        }

        // Retrieve all parameters of this function.
        SymEnumSymbols(this->m_hProcess, NULL, NULL, EnumParamsCallback, &resolvedParameters);
    }
예제 #4
0
BOOL CShadowSSDTMgr::GetShadowSSDTNativeAddrBySymbol()
{
	BOOL			boRetn;
	PDWORD			pW32pServiceTable = 0;
	DWORD			dwload = 0;
	PLOADED_IMAGE	ploadImage = {0};
	char			imgPath[MAX_PATH];

	// 初始化
	if ( !InitSymbolsHandler() )
	{
		return FALSE;
	}

	// 获取系统目录"C:\WINDOWS\system32"
	GetSystemDirectory( imgPath, MAX_PATH );
	// 加载模块
	ploadImage = ImageLoad( "win32k.sys", imgPath );

	// 加载符号"C:\WINDOWS\system32\win32k.sys"
	strcat( imgPath, "\\win32k.sys" );
	dwload=SymLoadModule ( g_ixerhProc, ploadImage->hFile,
									imgPath, "win32k.pdb",
									0, ploadImage->SizeOfImage );

	boRetn=SymEnumSymbols( g_ixerhProc, dwload, NULL, (PSYM_ENUMERATESYMBOLS_CALLBACK)EnumSymRoutine, NULL );
	if (g_W32pServiceTable)
	{
		pW32pServiceTable = (PDWORD)( g_W32pServiceTable - dwload + (DWORD)ploadImage->MappedAddress );
		boRetn=SymEnumSymbols( g_ixerhProc, dwload, NULL, (PSYM_ENUMERATESYMBOLS_CALLBACK)EnumSymRoutine, pW32pServiceTable );
	}

	ImageUnload(ploadImage);
	SymCleanup(g_ixerhProc);
	return boRetn;
}
예제 #5
0
int symbol_info_locals(void)
{
    IMAGEHLP_STACK_FRAME        ihsf;
    ADDRESS64                   addr;

    stack_get_current_frame(&ihsf);
    addr.Mode = AddrModeFlat;
    addr.Offset = ihsf.InstructionOffset;
    print_address(&addr, FALSE);
    dbg_printf(": (%08lx)\n", (DWORD_PTR)ihsf.FrameOffset);
    SymEnumSymbols(dbg_curr_process->handle, 0, NULL, info_locals_cb, (void*)(DWORD_PTR)ihsf.FrameOffset);

    return TRUE;

}
예제 #6
0
BOOL symbol_is_local(const char* name)
{
    struct sgv_data             sgv;
    IMAGEHLP_STACK_FRAME        ihsf;

    sgv.num        = 0;
    sgv.num_thunks = 0;
    sgv.name       = name;
    sgv.do_thunks  = FALSE;

    if (stack_get_current_frame(&ihsf))
    {
        sgv.frame_offset = ihsf.FrameOffset;
        SymEnumSymbols(dbg_curr_process->handle, 0, name, sgv_cb, (void*)&sgv);
    }
    return sgv.num > 0;
}
예제 #7
0
static void stack_print_addr_and_args(int nf)
{
    char                        buffer[sizeof(SYMBOL_INFO) + 256];
    SYMBOL_INFO*                si = (SYMBOL_INFO*)buffer;
    IMAGEHLP_STACK_FRAME        ihsf;
    IMAGEHLP_LINE64             il;
    IMAGEHLP_MODULE             im;
    DWORD64                     disp64;

    print_bare_address(&dbg_curr_thread->frames[nf].addr_pc);

    stack_get_frame(nf, &ihsf);

    /* grab module where symbol is. If we don't have a module, we cannot print more */
    im.SizeOfStruct = sizeof(im);
    if (!SymGetModuleInfo(dbg_curr_process->handle, ihsf.InstructionOffset, &im))
        return;

    si->SizeOfStruct = sizeof(*si);
    si->MaxNameLen   = 256;
    if (SymFromAddr(dbg_curr_process->handle, ihsf.InstructionOffset, &disp64, si))
    {
        struct sym_enum se;
        DWORD           disp;

        dbg_printf(" %s", si->Name);
        if (disp64) dbg_printf("+0x%lx", (DWORD_PTR)disp64);

        SymSetContext(dbg_curr_process->handle, &ihsf, NULL);
        se.first = TRUE;
        se.frame = ihsf.FrameOffset;
        dbg_printf("(");
        SymEnumSymbols(dbg_curr_process->handle, 0, NULL, sym_enum_cb, &se);
        dbg_printf(")");

        il.SizeOfStruct = sizeof(il);
        if (SymGetLineFromAddr64(dbg_curr_process->handle,
                                 ihsf.InstructionOffset, &disp, &il))
            dbg_printf(" [%s:%u]", il.FileName, il.LineNumber);
        dbg_printf(" in %s", im.ModuleName);
    }
    else dbg_printf(" in %s (+0x%lx)",
                        im.ModuleName, (DWORD_PTR)(ihsf.InstructionOffset - im.BaseOfImage));
}
예제 #8
0
//--------------------------------------------------------------------------------------
ULONGLONG GetSymbolByName(char *lpszModuleName, HMODULE hModule, char *lpszName)
{
    ULONGLONG Ret = 0;

    // try to load debug symbols for module
    if (SymLoadModuleEx(GetCurrentProcess(), NULL, lpszModuleName, NULL, (DWORD64)hModule, 0, NULL, 0))
    {
        ENUM_SYM_PARAM Param;

        Param.Address = NULL;
        Param.lpszName = lpszName;

        // get specified symbol address by name
        if (!SymEnumSymbols(
            GetCurrentProcess(),
            (DWORD64)hModule,
            NULL,
            EnumSymbolsProc,
            &Param))
        {                    
            DbgMsg(__FILE__, __LINE__, "SymEnumSymbols() ERROR %d\n", GetLastError());
        }

        if (Param.Address == NULL)
        {
            DbgMsg(__FILE__, __LINE__, __FUNCTION__"() ERROR: Can't locate symbol\n");
        }
        else
        {
            Ret = Param.Address;
        }

        // unload symbols
        SymUnloadModule64(GetCurrentProcess(), (DWORD64)hModule);
    }
    else
    {
        DbgMsg(__FILE__, __LINE__, "SymLoadModuleEx() ERROR %d\n", GetLastError());
    }

    return Ret;
}
예제 #9
0
void symbol_info(const char* str)
{
    char        buffer[512];
    DWORD       opt;

    if (strlen(str) + 3 >= sizeof(buffer))
    {
        dbg_printf("Symbol too long (%s)\n", str);
        return;
    }
    buffer[0] = '*';
    buffer[1] = '!';
    strcpy(&buffer[2], str);
    /* this is a wine specific options to return also ELF modules in the
     * enumeration
     */
    SymSetOptions((opt = SymGetOptions()) | 0x40000000);
    SymEnumSymbols(dbg_curr_process->handle, 0, buffer, symbols_info_cb, NULL);
    SymSetOptions(opt);
}
예제 #10
0
/** 
 * 
 * Enumerates one module in a process
 * 
 * @param       dwDllBases_i - Base address of module to enumerate
 * @return      bool         - Return true
 * @exception   Nil
 * @see         Nil
 * @since       1.0
 */
bool ProcessSymbolCollection::EnumerateModuleSymbols( DWORD dwDllBases_i, 
                                                      SymbolCollection*& pModSymColl_o,
                                                      LPCTSTR lpctszModuleFileName_i,
                                                      const DWORD dwModuleSize_i,
                                                      const bool bRefresh_i )
{
    UNREFERENCED_PARAMETER( lpctszModuleFileName_i );
    UNREFERENCED_PARAMETER( dwModuleSize_i );

    bool bFound = false;
    if( bRefresh_i )
    {
        // Find in map
        bFound = m_ModSymMap.Lookup( dwDllBases_i, pModSymColl_o ) != FALSE;

        if( bFound )
        {
            // Remove entry from map
            m_ModSymMap.RemoveKey( dwDllBases_i );
            delete pModSymColl_o;
        }// End if
    }// End if

    if( bRefresh_i || !m_ModSymMap.Lookup( dwDllBases_i, pModSymColl_o ))
    {
        // Allocate a new module symbol collection
        pModSymColl_o = new SymbolCollection;
    	SymEnumSymbols( m_hProcess, 
						dwDllBases_i, 
						0, 
						EnumModuleSymbolsCB,  
						pModSymColl_o );

        // Add this entry to map
        m_ModSymMap[dwDllBases_i] = pModSymColl_o;
    }// End if

    return true;
}// End Enumerate
예제 #11
0
const bool Symbols::EnumerateModuleSymbols(const char * const pModulePath, const DWORD64 dwBaseAddress)
{
    DWORD64 dwBaseOfDll = SymLoadModuleEx(m_hProcess, m_hFile, pModulePath, nullptr,
        dwBaseAddress, 0, nullptr, 0);
    if (dwBaseOfDll == 0)
    {
        fprintf(stderr, "Could not load modules for %s. Error = %X.\n",
            pModulePath, GetLastError());
        return false;
    }

    UserContext userContext = { this, pModulePath };
    const bool bSuccess = 
       BOOLIFY(SymEnumSymbols(m_hProcess, dwBaseOfDll, "*!*", SymEnumCallback, &userContext));
    if (!bSuccess)
    {
        fprintf(stderr, "Could not enumerate symbols for %s. Error = %X.\n",
            pModulePath, GetLastError());
    }

    return bSuccess;
}
예제 #12
0
int Pxlookup_by_name(struct ps_prochandle *P, Lmid_t lmid, const char *oname, const char *sname, GElf_Sym *symp, void *sip)
{
    int ol = 0, sl = 0;
    char *Mask;
    const char *obj = oname;
    struct lookup_uc uc;

    if (sname == NULL)
        return -1;

    if (oname == NULL)
        obj = "*";
    else if (strcmp("a.out", oname) == 0)
        obj = P->exe_module->name;
    Mask = malloc((ol = strlen(obj)) + (sl = strlen(sname)) + 2);
    strncpy(Mask, obj, ol);
    strncpy(&Mask[ol++], "!", 1);
    strncpy(&Mask[ol], sname, sl);
    Mask[ol + sl] = 0;

    memset(symp, 0, sizeof(GElf_Sym));
    uc.ps = P;
    uc.cd = symp;
    uc.f = NULL;

    if (SymEnumSymbols(P->phandle, 0, Mask, MyEnumSymbolsCallback, &uc) == FALSE) {
        dprintf("SymEnumSymbols failed (%d): %x\n", P->pid, GetLastError());
        free(Mask);
        return -1;
    }
    free(Mask);

    if (symp->st_value != 0)
        return 0;

    return dw_lookup_by_name(P, oname, sname, symp);
}
예제 #13
0
int enumerate_symbols(Context * ctx, int frame, EnumerateSymbolsCallBack * call_back, void * args) {
    ULONG64 buffer[(sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)];
    SYMBOL_INFO * symbol = (SYMBOL_INFO *)buffer;
    IMAGEHLP_STACK_FRAME stack_frame;
    EnumerateSymbolsContext enum_context;
    HANDLE process = get_context_handle(ctx->parent == NULL ? ctx : ctx->parent);

    symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
    symbol->MaxNameLen = MAX_SYM_NAME;

    if (frame == STACK_TOP_FRAME) frame = get_top_frame(ctx);
    if (frame == STACK_TOP_FRAME) return -1;
    if (get_stack_frame(ctx, frame, 0, &stack_frame) < 0) return -1;

    if (!SymSetContext(process, &stack_frame, NULL)) {
        DWORD err = GetLastError();
        if (err == ERROR_SUCCESS) {
            /* Don't know why Windows does that */
        }
        else {
            set_win32_errno(err);
            return -1;
        }
    }

    enum_context.ctx = ctx;
    enum_context.frame = frame;
    enum_context.call_back = call_back;
    enum_context.args = args;

    if (!SymEnumSymbols(process, 0, NULL, enumerate_symbols_proc, &enum_context)) {
        set_win32_errno(GetLastError());
        return -1;
    }

    return 0;
}
예제 #14
0
파일: cmdsym.c 프로젝트: jpassing/ntrace
BOOL JpfsvpSearchSymbolCommand(
	__in PJPFSV_COMMAND_PROCESSOR_STATE ProcessorState,
	__in PCWSTR CommandName,
	__in UINT Argc,
	__in PCWSTR* Argv
	)
{
	SEARCH_SYMBOL_CTX Ctx;
	HANDLE Process = JpfsvGetProcessHandleContext( ProcessorState->Context );

	UNREFERENCED_PARAMETER( CommandName );

	if ( Argc < 1 )
	{
		( ProcessorState->OutputRoutine ) ( L"Usage: x <mask>\n" );
		return FALSE;
	}

	Ctx.OutputRoutine = ProcessorState->OutputRoutine;
	Ctx.ContextHandle = ProcessorState->Context;

	if ( ! SymEnumSymbols(
		Process,
		0,
		Argv[ 0 ],
		JpfsvsOutputSymbol,
		&Ctx ) )
	{
		DWORD Err = GetLastError();
		JpfsvpOutputError( 
			ProcessorState, HRESULT_FROM_WIN32( Err ) );
		return FALSE;
	}

	return TRUE;
}
예제 #15
0
static VOID TestTraceNotepadAndDoHarshCleanup()
{
	PROCESS_INFORMATION pi;
	JPFSV_HANDLE NpCtx;
	PROC_SET Set;
	DWORD_PTR FailedProc;

	TEST_OK( CdiagCreateSession( NULL, NULL, &DiagSession ) );

	//
	// Launch notepad.
	//
	LaunchNotepad( &pi );

	//
	// Give notepad some time to start...
	//
	Sleep( 1000 );

	//
	// Start a trace.
	//
	TEST_OK( JpfsvLoadContext( pi.dwProcessId, NULL, &NpCtx ) );
	TEST_OK( JpfsvAttachContext( NpCtx, JpfsvTracingTypeDefault, NULL ) );

	//
	// Instrument some procedures.
	//
	Set.Count = 0;
	Set.ContextHandle = NpCtx;
	Set.Process = JpfsvGetProcessHandleContext( NpCtx );
	TEST( Set.Process );

	TEST( SymEnumSymbols(
		Set.Process,
		0,
		L"user32!*",
		AddProcedureSymCallback,
		&Set ) );

	TEST_OK( JpfsvStartTraceContext(
		NpCtx,
		5,
		1024,
		DiagSession ) );
	TEST_OK( JpfsvSetTracePointsContext(
		NpCtx,
		JpfsvAddTracepoint,
		Set.Count,
		Set.Procedures,
		&FailedProc ) );
	
	//
	// Skip stopping, skip detach.
	//
	TEST_OK( JpfsvUnloadContext( NpCtx ) );
	TEST_OK( CdiagDereferenceSession( DiagSession ) );

	//
	// Kill notepad.
	//
	TEST( TerminateProcess( pi.hProcess, 0 ) );
	CloseHandle( pi.hProcess );
	CloseHandle( pi.hThread );

	//
	// Wait i.o. not to confuse further tests with dying process.
	//
	Sleep( 1000 );
}
예제 #16
0
int main(int argc, char *argv[]) {
  DWORD  error;
  HANDLE process;
  ULONG64 module_base;
  SYM_CONTEXT ctx;
  int i;
  char* search;
  char* filename = NULL;
  int rv = 0;
  /* We may add SYMOPT_UNDNAME if --demangle is specified: */
  DWORD symopts = SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG;

  for (i = 1; i < argc; i++) {
    if (strcmp(argv[i], "--demangle") == 0 || strcmp(argv[i], "-C") == 0) {
      symopts |= SYMOPT_UNDNAME;
    } else if (strcmp(argv[i], "--help") == 0) {
      usage();
      exit(0);
    } else {
      break;
    }
  }
  if (i != argc - 1) {
    usage();
    exit(1);
  }
  filename = argv[i];

  process = GetCurrentProcess();

  if (!SymInitialize(process, NULL, FALSE)) {
    error = GetLastError();
    fprintf(stderr, "SymInitialize returned error : %d\n", error);
    return 1;
  }

  search = malloc(SEARCH_CAP);
  if (SymGetSearchPath(process, search, SEARCH_CAP)) {
    if (strlen(search) + sizeof(";" WEBSYM) > SEARCH_CAP) {
      fprintf(stderr, "Search path too long\n");
      SymCleanup(process);
      return 1;
    }
    strcat(search, ";" WEBSYM);
  } else {
    error = GetLastError();
    fprintf(stderr, "SymGetSearchPath returned error : %d\n", error);
    rv = 1;                   /* An error, but not a fatal one */
    strcpy(search, WEBSYM);   /* Use a default value */
  }
  if (!SymSetSearchPath(process, search)) {
    error = GetLastError();
    fprintf(stderr, "SymSetSearchPath returned error : %d\n", error);
    rv = 1;                   /* An error, but not a fatal one */
 }

  SymSetOptions(symopts);
  module_base = SymLoadModuleEx(process, NULL, filename, NULL, 0, 0, NULL, 0);
  if (!module_base) {
    /* SymLoadModuleEx failed */
    error = GetLastError();
    fprintf(stderr, "SymLoadModuleEx returned error : %d for %s\n",
            error, filename);
    SymCleanup(process);
    return 1;
  }

  ShowSymbolInfo(process, module_base);

  memset(&ctx, 0, sizeof(ctx));
  ctx.module_base = module_base;
  if (!SymEnumSymbols(process, module_base, NULL, EnumSymProc, &ctx)) {
    error = GetLastError();
    fprintf(stderr, "SymEnumSymbols returned error: %d\n", error);
    rv = 1;
  } else {
    DWORD j;
    qsort(ctx.syms, ctx.syms_len, sizeof(ctx.syms[0]), sym_cmp);
    for (j = 0; j < ctx.syms_len; j++) {
      printf("%016I64x X %s\n", ctx.syms[j].addr, ctx.syms[j].name);
    }
    /* In a perfect world, maybe we'd clean up ctx's memory? */
  }
  SymUnloadModule64(process, module_base);
  SymCleanup(process);
  return rv;
}
예제 #17
0
/***********************************************************************
 *           symbol_get_lvalue
 *
 * Get the address of a named symbol.
 * Return values:
 *      sglv_found:   if the symbol is found
 *      sglv_unknown: if the symbol isn't found
 *      sglv_aborted: some error occurred (likely, many symbols of same name exist,
 *          and user didn't pick one of them)
 */
enum sym_get_lval symbol_get_lvalue(const char* name, const int lineno,
                                    struct dbg_lvalue* rtn, BOOL bp_disp)
{
    struct sgv_data             sgv;
    int		                i;
    char                        buffer[512];
    DWORD                       opt;
    IMAGEHLP_STACK_FRAME        ihsf;

    if (strlen(name) + 4 > sizeof(buffer))
    {
        WINE_WARN("Too long symbol (%s)\n", name);
        return sglv_unknown;
    }

    sgv.num        = 0;
    sgv.num_thunks = 0;
    sgv.name       = &buffer[2];
    sgv.do_thunks  = DBG_IVAR(AlwaysShowThunks);

    if (strchr(name, '!'))
    {
        strcpy(buffer, name);
    }
    else
    {
        buffer[0] = '*';
        buffer[1] = '!';
        strcpy(&buffer[2], name);
    }

    /* this is a wine specific options to return also ELF modules in the
     * enumeration
     */
    SymSetOptions((opt = SymGetOptions()) | 0x40000000);
    SymEnumSymbols(dbg_curr_process->handle, 0, buffer, sgv_cb, (void*)&sgv);

    if (!sgv.num)
    {
        const char*   ptr = strchr(name, '!');
        if ((ptr && ptr[1] != '_') || (!ptr && *name != '_'))
        {
            if (ptr)
            {
                int offset = ptr - name;
                memcpy(buffer, name, offset + 1);
                buffer[offset + 1] = '_';
                strcpy(&buffer[offset + 2], ptr + 1);
            }
            else
            {
                buffer[0] = '*';
                buffer[1] = '!';
                buffer[2] = '_';
                strcpy(&buffer[3], name);
            }
            SymEnumSymbols(dbg_curr_process->handle, 0, buffer, sgv_cb, (void*)&sgv);
        }
    }
    SymSetOptions(opt);

    /* now grab local symbols */
    if (stack_get_current_frame(&ihsf) && sgv.num < NUMDBGV)
    {
        sgv.frame_offset = ihsf.FrameOffset;
        SymEnumSymbols(dbg_curr_process->handle, 0, name, sgv_cb, (void*)&sgv);
    }

    if (!sgv.num)
    {
        dbg_printf("No symbols found for %s\n", name);
        return sglv_unknown;
    }

    /* recompute potential offsets for functions (linenumber, skip prolog) */
    for (i = 0; i < sgv.num; i++)
    {
        if (sgv.syms[i].flags & (SYMFLAG_REGISTER|SYMFLAG_REGREL|SYMFLAG_LOCAL|SYMFLAG_THUNK))
            continue;

        if (lineno == -1)
        {
            struct dbg_type     type;
            ULONG64             addr;

            type.module = sgv.syms[i].lvalue.type.module;
            type.id     = sgv.syms[i].sym_info;
            if (bp_disp && symbol_get_debug_start(&type, &addr))
                sgv.syms[i].lvalue.addr.Offset = addr;
        }
        else
        {
            DWORD               disp;
            IMAGEHLP_LINE       il;
            BOOL                found = FALSE;

            il.SizeOfStruct = sizeof(il);
            SymGetLineFromAddr(dbg_curr_process->handle,
                               (DWORD)memory_to_linear_addr(&sgv.syms[i].lvalue.addr),
                               &disp, &il);
            do
            {
                if (lineno == il.LineNumber)
                {
                    sgv.syms[i].lvalue.addr.Offset = il.Address;
                    found = TRUE;
                    break;
                }
            } while (SymGetLineNext(dbg_curr_process->handle, &il));
            if (!found)
                WINE_FIXME("No line (%d) found for %s (setting to symbol start)\n",
                           lineno, name);
        }
    }

    i = 0;
    if (dbg_interactiveP)
    {
        if (sgv.num - sgv.num_thunks > 1 || /* many symbols non thunks (and showing only non thunks) */
            (sgv.num > 1 && DBG_IVAR(AlwaysShowThunks)) || /* many symbols (showing symbols & thunks) */
            (sgv.num == sgv.num_thunks && sgv.num_thunks > 1))
        {
            dbg_printf("Many symbols with name '%s', "
                       "choose the one you want (<cr> to abort):\n", name);
            for (i = 0; i < sgv.num; i++) 
            {
                if (sgv.num - sgv.num_thunks > 1 && (sgv.syms[i].flags & SYMFLAG_THUNK) && !DBG_IVAR(AlwaysShowThunks))
                    continue;
                dbg_printf("[%d]: ", i + 1);
                if (sgv.syms[i].flags & SYMFLAG_LOCAL)
                {
                    dbg_printf("%s %sof %s\n",
                               sgv.syms[i].flags & SYMFLAG_PARAMETER ? "Parameter" : "Local variable",
                               sgv.syms[i].flags & (SYMFLAG_REGISTER|SYMFLAG_REGREL) ? "(in a register) " : "",
                               name);
                }
                else if (sgv.syms[i].flags & SYMFLAG_THUNK) 
                {
                    print_address(&sgv.syms[i].lvalue.addr, TRUE);
                    /* FIXME: should display where the thunks points to */
                    dbg_printf(" thunk %s\n", name);
                }
                else
                {
                    print_address(&sgv.syms[i].lvalue.addr, TRUE);
                    dbg_printf("\n");
                }
            }
            do
            {
                i = 0;
                if (input_read_line("=> ", buffer, sizeof(buffer)))
                {
                    if (buffer[0] == '\0') return sglv_aborted;
                    i = atoi(buffer);
                    if (i < 1 || i > sgv.num)
                        dbg_printf("Invalid choice %d\n", i);
                }
                else return sglv_aborted;
            } while (i < 1 || i > sgv.num);

            /* The array is 0-based, but the choices are 1..n, 
             * so we have to subtract one before returning.
             */
            i--;
        }
    }
    else
    {
        /* FIXME: could display the list of non-picked up symbols */
        if (sgv.num > 1)
            dbg_printf("More than one symbol named %s, picking the first one\n", name);
    }
    *rtn = sgv.syms[i].lvalue;
    return sglv_found;
}
예제 #18
0
파일: createspec.c 프로젝트: nsxz/reactos
HRESULT
ParseImageSymbols(
    _In_ HMODULE hmod,
    _Inout_ PEXPORT_DATA pExportData)
{
    DWORD64 dwModuleBase;
    ULONG i;
    IMAGEHLP_STACK_FRAME StackFrame;
    SYMINFO_EX sym;

    dwModuleBase = (DWORD_PTR)hmod;

    /* Loop through all exports */
    for (i = 0; i < pExportData->cNumberOfExports; i++)
    {
        PEXPORT pExport = &pExportData->aExports[i];
        ULONG64 ullFunction = dwModuleBase + pExportData->aExports[i].ulRva;
        ULONG64 ullDisplacement;

        /* Check if this is a forwarder */
        if (pExport->pszForwarder != NULL)
        {
            /* Load the module and get the function address */
            ullFunction = GetFunctionFromForwarder(pExport->pszForwarder);
            if (ullFunction == 0)
            {
                printf("Failed to get function for forwarder '%s'. Skipping.\n", pExport->pszForwarder);
                continue;
            }
        }

        RtlZeroMemory(&sym, sizeof(sym));
        sym.si.SizeOfStruct = sizeof(SYMBOL_INFO);
        sym.si.MaxNameLen = MAX_SYMBOL_NAME;

        /* Try to find the symbol */
        if (!SymFromAddr(ghProcess, ullFunction, &ullDisplacement, &sym.si))
        {
            error("Error: SymFromAddr() failed.");
            continue;
        }

        /* Get the symbol name */
        pExport->pszSymbol = _strdup(sym.si.Name);

        /* Check if it is a function */
        if (sym.si.Tag == SymTagFunction)
        {
            /* Get the calling convention */
            if (!SymGetTypeInfo(ghProcess,
                                dwModuleBase,
                                sym.si.TypeIndex,
                                TI_GET_CALLING_CONVENTION,
                                &pExport->dwCallingConvention))
            {
                /* Fall back to __stdcall */
                pExport->dwCallingConvention = CV_CALL_NEAR_STD;
            }

            /* Set the context to the function address */
            RtlZeroMemory(&StackFrame, sizeof(StackFrame));
            StackFrame.InstructionOffset = ullFunction;
            if (!SymSetContext(ghProcess, &StackFrame, NULL))
            {
                error("SymSetContext failed for i = %u.", i);
                continue;
            }

            /* Enumerate all symbols for this function */
            if (!SymEnumSymbols(ghProcess,
                                0, // use SymSetContext
                                NULL,
                                EnumParametersCallback,
                                pExport))
            {
                error("SymEnumSymbols failed for i = %u.", i);
                continue;
            }
        }
        else if (sym.si.Tag == SymTagPublicSymbol)
        {
            pExport->dwCallingConvention = CV_CALL_NEAR_STD;
        }
        else if (sym.si.Tag == SymTagData)
        {
            pExport->fData = TRUE;
        }
    }

    return S_OK;
}
예제 #19
0
/***********************************************************************
 *           symbol_get_line
 *
 * Find the symbol nearest to a given address.
 * Returns sourcefile name and line number in a format that the listing
 * handler can deal with.
 */
BOOL symbol_get_line(const char* filename, const char* name, IMAGEHLP_LINE* line)
{
    struct sgv_data     sgv;
    char                buffer[512];
    DWORD               opt, disp, linear;
    unsigned            i, found = FALSE;
    IMAGEHLP_LINE       il;

    sgv.num        = 0;
    sgv.num_thunks = 0;
    sgv.name       = &buffer[2];
    sgv.do_thunks  = FALSE;

    buffer[0] = '*';
    buffer[1] = '!';
    strcpy(&buffer[2], name);

    /* this is a wine specific options to return also ELF modules in the
     * enumeration
     */
    SymSetOptions((opt = SymGetOptions()) | 0x40000000);
    if (!SymEnumSymbols(dbg_curr_process->handle, 0, buffer, sgv_cb, (void*)&sgv))
    {
        SymSetOptions(opt);
        return FALSE;
    }

    if (!sgv.num && (name[0] != '_'))
    {
        buffer[2] = '_';
        strcpy(&buffer[3], name);
        if (!SymEnumSymbols(dbg_curr_process->handle, 0, buffer, sgv_cb, (void*)&sgv))
        {
            SymSetOptions(opt);
            return FALSE;
        }
    }
    SymSetOptions(opt);

    for (i = 0; i < sgv.num; i++)
    {
        linear = (DWORD)memory_to_linear_addr(&sgv.syms[i].lvalue.addr);

        il.SizeOfStruct = sizeof(il);
        if (!SymGetLineFromAddr(dbg_curr_process->handle, linear, &disp, &il))
            continue;
        if (filename && strcmp(line->FileName, filename)) continue;
        if (found)
        {
            WINE_FIXME("Several found, returning first (may not be what you want)...\n");
            break;
        }
        found = TRUE;
        *line = il;
    }
    if (!found)
    {
        if (filename)   dbg_printf("No such function %s in %s\n", name, filename);
	else            dbg_printf("No such function %s\n", name);
        return FALSE;
    }
    return TRUE;
}
예제 #20
0
static VOID TestTraceKernel()
{
	ULONG BufferCount;
	ULONG BufferSize;
	PROC_SET Set;
	DWORD_PTR FailedProc;
	UINT Tracepoints, Count;
	UINT EnumCount;
	JPFSV_TRACEPOINT Tracepnt;
	HRESULT Hr;
	JPFSV_HANDLE KernelCtx;
	JPFSV_TRACING_TYPE TracingType;
	ULONG TypesTested = 0;
	
	TEST_OK( CdiagCreateSession( NULL, NULL, &DiagSession ) );

	for ( TracingType = JpfsvTracingTypeDefault;
		  TracingType <= JpfsvTracingTypeMax;
		  TracingType++ )
	{
		UINT Index;
		BOOL Instrumentable;
		WCHAR LogFile[ MAX_PATH ];
		UINT PaddingSize;

		TEST_OK( StringCchPrintf( 
			LogFile, _countof( LogFile ), L"__kern%d.log",  TracingType ) );

		//
		// Start a trace.
		//
		KernelCtx = NULL;
		Hr = JpfsvLoadContext( JPFSV_KERNEL, NULL, &KernelCtx );
		if ( Hr == JPFSV_E_UNSUP_ON_WOW64 )
		{
			CFIX_INCONCLUSIVE( L"Not supported on WOW64" );
			return;
		}
		TEST_OK( Hr );
		
		TEST( JPFSV_E_NO_TRACESESSION == 
			JpfsvGetTracepointContext( KernelCtx, 0xF00, &Tracepnt ) );

		DeleteFile( LogFile );
		if ( TracingType != JpfsvTracingTypeWmk )
		{
			TEST( E_INVALIDARG == JpfsvAttachContext( KernelCtx, TracingType, NULL ) );
			Hr = JpfsvAttachContext( KernelCtx, TracingType, LogFile );
		}
		else
		{
			TEST( E_INVALIDARG == JpfsvAttachContext( KernelCtx, TracingType, LogFile ) );
			Hr = JpfsvAttachContext( KernelCtx, TracingType, NULL );
		}
		if ( Hr == JPFSV_E_UNSUPPORTED_TRACING_TYPE ||
			 Hr == HRESULT_FROM_NT( 0xC0049300L ) ) // STATUS_KFBT_KERNEL_NOT_SUPPORTED
		{
			continue;
		}

		TEST_OK( Hr );

		if ( TracingType == JpfsvTracingTypeWmk )
		{
			BufferCount = 0;
			BufferSize = 0;
		}
		else
		{
			BufferCount = 5;
			BufferSize = 1024;
		}

		//
		// Instrument some procedures.
		//
		Set.Count = 0;
		Set.ContextHandle = KernelCtx;
		Set.Process = JpfsvGetProcessHandleContext( KernelCtx );
		TEST( Set.Process );

		//
		// Not all patchable...
		//
		TEST( SymEnumSymbols(
			Set.Process,
			0,
			L"tcpip!*",
			AddProcedureSymCallback,
			&Set ) );

		TEST_OK( JpfsvStartTraceContext(
			KernelCtx,
			BufferCount,
			BufferSize,
			DiagSession ) );
		TEST( E_UNEXPECTED == JpfsvStartTraceContext(
			KernelCtx,
			BufferCount,
			BufferSize,
			DiagSession ) );

		TEST( Set.Count > 0 );

		TEST_OK( JpfsvCountTracePointsContext( KernelCtx, &Count ) );
		TEST( 0 == Count );

		TEST_STATUS( ( ULONG ) HRESULT_FROM_NT( STATUS_FBT_PROC_NOT_PATCHABLE ), 
			JpfsvSetTracePointsContext(
				KernelCtx,
				JpfsvAddTracepoint,
				Set.Count,
				Set.Procedures,
				&FailedProc ) );

		//
		// Instrumentable...
		//
		Set.Count = 0;
		Set.ContextHandle = KernelCtx;
		Set.Process = JpfsvGetProcessHandleContext( KernelCtx );
		TEST( SymEnumSymbols(
			Set.Process,
			0,
			IsVistaOrLater()
				? L"tcpip!IPReg*"
				: L"tcpip!IPRc*",
			AddProcedureSymCallback,
			&Set ) );
		TEST( Set.Count > 0 );
		for ( Index = 0; Index < Set.Count; Index++ )
		{
			TEST_OK( JpfsvCheckProcedureInstrumentability(
				KernelCtx,
				Set.Procedures[ Index ],
				&Instrumentable,
				&PaddingSize ) );
			TEST( Instrumentable );
			TEST( PaddingSize == 5 );
		}

		//
		// Not instrumentable...
		//
		Set.Count = 0;
		Set.ContextHandle = KernelCtx;
		Set.Process = JpfsvGetProcessHandleContext( KernelCtx );
		TEST( SymEnumSymbols(
			Set.Process,
			0,
			IsVistaOrLater()
				? L"tcpip!__report_gsfailure"
				: L"tcpip!_wcsicmp",
			AddProcedureSymCallback,
			&Set ) );
		TEST( Set.Count > 0 );
		TEST_OK( JpfsvCheckProcedureInstrumentability(
			KernelCtx,
			Set.Procedures[ 0 ],
			&Instrumentable,
			&PaddingSize ) );
		TEST( ! Instrumentable );
		TEST( PaddingSize == 0 );

		//
		// All patchable...
		//
		Set.Count = 0;
		Set.ContextHandle = KernelCtx;
		Set.Process = JpfsvGetProcessHandleContext( KernelCtx );
		TEST( Set.Process );

		TEST( SymEnumSymbols(
			Set.Process,
			0,
			IsVistaOrLater()
				? L"tcpip!IPReg*"
				: L"tcpip!IPRc*",
			AddProcedureSymCallback,
			&Set ) );
		TEST( Set.Count >= 3 );

		TEST_OK( JpfsvSetTracePointsContext(
			KernelCtx,
			JpfsvAddTracepoint,
			Set.Count,
			Set.Procedures,
			&FailedProc ) );

		// again - should be a noop.
		TEST_OK( JpfsvSetTracePointsContext(
			KernelCtx,
			JpfsvAddTracepoint,
			Set.Count,
			Set.Procedures,
			&FailedProc ) );
		TEST( FailedProc == 0 );


		TEST_OK( JpfsvCountTracePointsContext( KernelCtx, &Tracepoints ) );
		TEST( Tracepoints > Set.Count / 2 );	// Duplicate-cleaned!
		TEST( Tracepoints <= Set.Count );

		TEST_OK( JpfsvGetTracepointContext( KernelCtx, Set.Procedures[ 0 ], &Tracepnt ) );
		TEST( Tracepnt.Procedure == Set.Procedures[ 0 ] );
		TEST( wcslen( Tracepnt.SymbolName ) );
		TEST( wcslen( Tracepnt.ModuleName ) );

		TEST( JPFSV_E_TRACEPOINT_NOT_FOUND == JpfsvGetTracepointContext( KernelCtx, 0xBA2, &Tracepnt ) );

		//
		// Count enum callbacks.
		//
		EnumCount = 0;
		TEST_OK( JpfsvEnumTracePointsContext(
			KernelCtx,
			CountTracepointsCallback,
			&EnumCount ) );
		TEST( EnumCount == Tracepoints );

		//
		// Stop while tracing active -> implicitly revoke all tracepoints.
		//
		TEST_OK( JpfsvStopTraceContext( KernelCtx, TRUE ) );
		TEST_OK( JpfsvCountTracePointsContext( KernelCtx, &Count ) );
		TEST( 0 == Count );

		//
		// Trace again.
		//
		DeleteFile( LogFile );
		TEST_OK( JpfsvStartTraceContext(
			KernelCtx,
			BufferCount,
			BufferSize,
			DiagSession ) );
		TEST_OK( JpfsvSetTracePointsContext(
			KernelCtx,
			JpfsvAddTracepoint,
			Set.Count,
			Set.Procedures,
			&FailedProc ) );
		TEST( FailedProc == 0 );

		TEST_OK( JpfsvCountTracePointsContext( KernelCtx, &Count ) );
		TEST( Tracepoints == Count );

		//
		// Clean shutdown.
		//
		TEST_OK( JpfsvSetTracePointsContext(
			KernelCtx,
			JpfsvRemoveTracepoint,
			Set.Count,
			Set.Procedures,
			&FailedProc ) );
		TEST( FailedProc == 0 );

		TEST_OK( JpfsvCountTracePointsContext( KernelCtx, &Count ) );
		TEST( 0 == Count );

		TEST_OK( JpfsvStopTraceContext( KernelCtx, TRUE ) );
		TEST_OK( DetachContextSafe( KernelCtx ) );
		TEST_OK( JpfsvUnloadContext( KernelCtx ) );

		TypesTested++;
	}

	TEST_OK( CdiagDereferenceSession( DiagSession ) );

	if ( TypesTested == 0 )
	{
		CFIX_INCONCLUSIVE( L"No TracingTypes supported" );
	}
}
예제 #21
0
static VOID TestDyingPeerWithTracing()
{
	PROCESS_INFORMATION pi;
	JPFSV_HANDLE NpCtx;
	PROC_SET Set;
	DWORD_PTR FailedProc;

	TEST_OK( CdiagCreateSession( NULL, NULL, &DiagSession ) );

	//
	// Launch notepad.
	//
	LaunchNotepad( &pi );

	//
	// Give notepad some time to start...
	//
	Sleep( 1000 );

	TEST_OK( JpfsvLoadContext( pi.dwProcessId, NULL, &NpCtx ) );
	TEST_OK( JpfsvAttachContext( NpCtx, JpfsvTracingTypeDefault, NULL ) );

	Set.Count = 0;
	Set.ContextHandle = NpCtx;
	Set.Process = JpfsvGetProcessHandleContext( NpCtx );
	TEST( Set.Process );

	TEST( SymEnumSymbols(
		Set.Process,
		0,
		L"user32!*",
		AddProcedureSymCallback,
		&Set ) );

	//
	// Instrument some procedures
	//
	TEST_OK( JpfsvStartTraceContext(
		NpCtx,
		5,
		1024,
		DiagSession ) );
	TEST( Set.Count > 0 );

	TEST_OK( JpfsvSetTracePointsContext(
		NpCtx,
		JpfsvAddTracepoint,
		Set.Count,
		Set.Procedures,
		&FailedProc ) );

	Sleep( 1000 );

	//
	// Kill notepad - the dying peer-mechanism should
	// kick in *on the read thread*.
	//
	TEST( TerminateProcess( pi.hProcess, 0 ) );
	CloseHandle( pi.hProcess );
	CloseHandle( pi.hThread );

	TEST( JPFSV_E_PEER_DIED == JpfsvStopTraceContext( NpCtx, TRUE ) );

	TEST_OK( DetachContextSafe( NpCtx ) );
	TEST_OK( JpfsvUnloadContext( NpCtx ) );

	TEST_OK( CdiagDereferenceSession( DiagSession ) );

	//
	// Wait i.o. not to confuse further tests with dying process.
	//
	Sleep( 1000 );
}
예제 #22
0
void write_stack_trace(PCONTEXT pContext, TextOutputStream& outputStream)
{
  HANDLE m_hProcess = GetCurrentProcess();
  DWORD dwMachineType = 0;

  CONTEXT context = *pContext;

  // Could use SymSetOptions here to add the SYMOPT_DEFERRED_LOADS flag
  if ( !SymInitialize( m_hProcess, (PSTR)environment_get_app_path(), TRUE ) )
  {
    return;
  }

  STACKFRAME sf;
  memset( &sf, 0, sizeof(sf) );

#ifdef _M_IX86
  // Initialize the STACKFRAME structure for the first call.  This is only
  // necessary for Intel CPUs, and isn't mentioned in the documentation.
  sf.AddrPC.Offset       = context.Eip;
  sf.AddrPC.Mode         = AddrModeFlat;
  sf.AddrStack.Offset    = context.Esp;
  sf.AddrStack.Mode      = AddrModeFlat;
  sf.AddrFrame.Offset    = context.Ebp;
  sf.AddrFrame.Mode      = AddrModeFlat;

  dwMachineType = IMAGE_FILE_MACHINE_I386;
#endif

  while ( 1 )
  {
    // Get the next stack frame
    if ( ! StackWalk(  dwMachineType,
                        m_hProcess,
                        GetCurrentThread(),
                        &sf,
                        &context,
                        0,
                        SymFunctionTableAccess,
                        SymGetModuleBase,
                        0 ) )
        break;

    if ( 0 == sf.AddrFrame.Offset ) // Basic sanity check to make sure
      break;                      // the frame is OK.  Bail if not.

    // Get the name of the function for this stack frame entry
    BYTE symbolBuffer[ sizeof(SYMBOL_INFO) + MAX_SYM_NAME ];
    PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)symbolBuffer;
    pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
    pSymbol->MaxNameLen = MAX_SYM_NAME;
                    
    DWORD64 symDisplacement = 0;    // Displacement of the input address,
                                    // relative to the start of the symbol

    IMAGEHLP_MODULE module = { sizeof(IMAGEHLP_MODULE) };
    if(SymGetModuleInfo(m_hProcess, sf.AddrPC.Offset, &module))
    {
      outputStream << module.ModuleName << "!";

      if ( SymFromAddr(m_hProcess, sf.AddrPC.Offset, &symDisplacement, pSymbol))
      {
        char undecoratedName[MAX_SYM_NAME];
        UnDecorateSymbolName(pSymbol->Name, undecoratedName, MAX_SYM_NAME, UNDNAME_COMPLETE);

        outputStream << undecoratedName;

        outputStream << "(";
        // Use SymSetContext to get just the locals/params for this frame
        IMAGEHLP_STACK_FRAME imagehlpStackFrame;
        imagehlpStackFrame.InstructionOffset = sf.AddrPC.Offset;
        SymSetContext( m_hProcess, &imagehlpStackFrame, 0 );

        // Enumerate the locals/parameters
        EnumerateSymbolsContext context(sf, outputStream);
        SymEnumSymbols( m_hProcess, 0, 0, EnumerateSymbolsCallback, &context );
        outputStream << ")";

        outputStream << " + " << Offset(reinterpret_cast<void*>(symDisplacement));

        // Get the source line for this stack frame entry
        IMAGEHLP_LINE lineInfo = { sizeof(IMAGEHLP_LINE) };
        DWORD dwLineDisplacement;
        if ( SymGetLineFromAddr( m_hProcess, sf.AddrPC.Offset,
                                &dwLineDisplacement, &lineInfo ) )
        {
          outputStream << " " << lineInfo.FileName << " line " << Unsigned(lineInfo.LineNumber); 
        }
      }
      else
      {
        outputStream << Address(reinterpret_cast<void*>(sf.AddrPC.Offset));
      }
    }

    outputStream << "\n";
  }

  SymCleanup(m_hProcess);

  return;
}
예제 #23
0
int dbg_help_client_t::init(char* path) {
    DWORD64 dwBaseAddr=0;

    int chars;
    char exe_path[MAX_PATH];
    chars = GetModuleFileName(NULL, exe_path, MAX_PATH);
    if (chars == 0) { 
        fprintf(stderr,"Could not find base path for XED executable\n");
        fflush(stderr);
        exit(1);
    }
    //fprintf(stderr,"EXE PATH %s\n", exe_path);
    char* dir = find_base_path(exe_path);
    //fprintf(stderr,"DIR      %s\n", dir);

    char* dbghelp = append3(dir,"\\","dbghelp.dll");
    //fprintf(stderr,"DBGHLP   %s\n", dbghelp);

    if (_access_s(dbghelp,4) != 0) {
        //fprintf(stderr,
        //    "WARNING: Could not find dbghelp.dll in xed.exe directory\n");
        //fflush(stderr);
        return 0;
    }    
    //fprintf(stderr,"FOUND DBGHELP\n");

    if (validate_version(dbghelp)) {
        fprintf(stderr,
            "WARNING: dbghelp.dll version is too old\n");
        fflush(stderr);
        return 0;
    }


    //FIXME: Add a version check for the dll ( ImagehlpApiVersion is NOT
    //the right thing)
        
    SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
    hProcess = GetCurrentProcess();
    
    if (SymInitialize(hProcess, NULL, FALSE))     {
        // nothing
    }
    else    {
        error = GetLastError();
        fprintf(stderr,"SymInitialize returned error : %d 0x%x\n",
                error, error);
        fflush(stderr);
        return 0;
    }


    actual_base = SymLoadModuleEx(hProcess, NULL, path, NULL, 
                                  dwBaseAddr, 0, NULL, 0);
    if (actual_base) {
        // nothing
    }
    else    {
        error = GetLastError();
        fprintf(stderr,"SymLoadModuleEx returned error : %d 0x%x\n", 
                error, error);
        fflush(stderr);
        return 0;
    }


    if (SymEnumerateModules64(hProcess, 
                        (PSYM_ENUMMODULES_CALLBACK64)enum_modules, this)) {
        // nothing
    }
    else    {
        error = GetLastError();
        fprintf(stderr,"SymEnumerateModules64 returned error : %d 0x%x\n",
               error, error);
        fflush(stderr);
        return 0;
    }

    if (SymEnumSymbols(hProcess, actual_base, 0, enum_sym, this))    {
        // nothing
    }
    else    {
        error = GetLastError();
        fprintf(stderr,"SymEnumSymbols failed: %d 0x%x\n", error, error);
        fflush(stderr);
        return 0;
    }

    make_symbol_vector(&sym_tab);
    initialized = true;
    return 1;
}
예제 #24
0
파일: symbol.c 프로젝트: Kelimion/wine
/***********************************************************************
 *           symbol_get_lvalue
 *
 * Get the address of a named symbol.
 * Return values:
 *      sglv_found:   if the symbol is found
 *      sglv_unknown: if the symbol isn't found
 *      sglv_aborted: some error occurred (likely, many symbols of same name exist,
 *          and user didn't pick one of them)
 */
enum sym_get_lval symbol_get_lvalue(const char* name, const int lineno,
                                    struct dbg_lvalue* rtn, BOOL bp_disp)
{
    struct sgv_data             sgv;
    int		                i;
    char                        buffer[512];
    DWORD                       opt;
    IMAGEHLP_STACK_FRAME        ihsf;

    if (strlen(name) + 4 > sizeof(buffer))
    {
        WINE_WARN("Too long symbol (%s)\n", name);
        return sglv_unknown;
    }

    sgv.num        = 0;
    sgv.num_thunks = 0;
    sgv.name       = &buffer[2];
    sgv.do_thunks  = DBG_IVAR(AlwaysShowThunks);

    if (strchr(name, '!'))
    {
        strcpy(buffer, name);
    }
    else
    {
        buffer[0] = '*';
        buffer[1] = '!';
        strcpy(&buffer[2], name);
    }

    /* this is a wine specific options to return also ELF modules in the
     * enumeration
     */
    SymSetOptions((opt = SymGetOptions()) | 0x40000000);
    SymEnumSymbols(dbg_curr_process->handle, 0, buffer, sgv_cb, (void*)&sgv);

    if (!sgv.num)
    {
        const char*   ptr = strchr(name, '!');
        if ((ptr && ptr[1] != '_') || (!ptr && *name != '_'))
        {
            if (ptr)
            {
                int offset = ptr - name;
                memcpy(buffer, name, offset + 1);
                buffer[offset + 1] = '_';
                strcpy(&buffer[offset + 2], ptr + 1);
            }
            else
            {
                buffer[0] = '*';
                buffer[1] = '!';
                buffer[2] = '_';
                strcpy(&buffer[3], name);
            }
            SymEnumSymbols(dbg_curr_process->handle, 0, buffer, sgv_cb, (void*)&sgv);
        }
    }
    SymSetOptions(opt);

    /* now grab local symbols */
    if (stack_get_current_frame(&ihsf) && sgv.num < NUMDBGV)
    {
        sgv.frame_offset = ihsf.FrameOffset;
        SymEnumSymbols(dbg_curr_process->handle, 0, name, sgv_cb, (void*)&sgv);
    }

    if (!sgv.num)
    {
        dbg_printf("No symbols found for %s\n", name);
        return sglv_unknown;
    }

    /* recompute potential offsets for functions (linenumber, skip prolog) */
    for (i = 0; i < sgv.num; i++)
    {
        if (sgv.syms[i].flags & (SYMFLAG_REGISTER|SYMFLAG_REGREL|SYMFLAG_LOCAL|SYMFLAG_THUNK))
            continue;

        if (lineno == -1)
        {
            struct dbg_type     type;
            ULONG64             addr;

            type.module = sgv.syms[i].lvalue.type.module;
            type.id     = sgv.syms[i].sym_info;
            if (bp_disp && symbol_get_debug_start(&type, &addr))
                sgv.syms[i].lvalue.addr.Offset = addr;
        }
        else
        {
            DWORD               disp;
            IMAGEHLP_LINE64     il;
            BOOL                found = FALSE;

            il.SizeOfStruct = sizeof(il);
            SymGetLineFromAddr64(dbg_curr_process->handle,
                                 (DWORD_PTR)memory_to_linear_addr(&sgv.syms[i].lvalue.addr),
				 &disp, &il);
            do
            {
                if (lineno == il.LineNumber)
                {
                    sgv.syms[i].lvalue.addr.Offset = il.Address;
                    found = TRUE;
                    break;
                }
            } while (SymGetLineNext64(dbg_curr_process->handle, &il));
            if (!found)
                WINE_FIXME("No line (%d) found for %s (setting to symbol start)\n",
                           lineno, name);
        }
    }

    if (sgv.num - sgv.num_thunks > 1 || /* many symbols non thunks (and showing only non thunks) */
        (sgv.num > 1 && DBG_IVAR(AlwaysShowThunks)) || /* many symbols (showing symbols & thunks) */
        (sgv.num == sgv.num_thunks && sgv.num_thunks > 1))
    {
        return symbol_current_picker(name, &sgv, rtn);
    }
    /* first symbol is the one we want:
     * - only one symbol found,
     * - or many symbols but only one non thunk when AlwaysShowThunks is FALSE
     */
    *rtn = sgv.syms[0].lvalue;
    return sglv_found;
}
예제 #25
0
static VOID TestTraceNotepad()
{
	PROCESS_INFORMATION pi;
	JPFSV_HANDLE NpCtx;
	PROC_SET Set;
	DWORD_PTR FailedProc;
	UINT Tracepoints, Count;
	UINT EnumCount = 0;
	JPFSV_TRACEPOINT Tracepnt;

	TEST_OK( CdiagCreateSession( NULL, NULL, &DiagSession ) );

	//
	// Launch notepad.
	//
	LaunchNotepad( &pi );

	//
	// Give notepad some time to start...
	//
	Sleep( 1000 );

	//
	// Start a trace.
	//
	TEST_OK( JpfsvLoadContext( pi.dwProcessId, NULL, &NpCtx ) );
	TEST( JPFSV_E_NO_TRACESESSION == JpfsvGetTracepointContext( NpCtx, 0xF00, &Tracepnt ) );

	TEST_OK( JpfsvAttachContext( NpCtx, JpfsvTracingTypeDefault, NULL ) );

	//
	// Instrument some procedures.
	//
	Set.Count = 0;
	Set.ContextHandle = NpCtx;
	Set.Process = JpfsvGetProcessHandleContext( NpCtx );
	TEST( Set.Process );

	TEST( SymEnumSymbols(
		Set.Process,
		0,
		L"user32!*",
		AddProcedureSymCallback,
		&Set ) );

	TEST_OK( JpfsvStartTraceContext(
		NpCtx,
		5,
		1024,
		DiagSession ) );
	TEST( E_UNEXPECTED == JpfsvStartTraceContext(
		NpCtx,
		5,
		1024,
		DiagSession ) );

	TEST( Set.Count > 0 );

	TEST_OK( JpfsvCountTracePointsContext( NpCtx, &Count ) );
	TEST( 0 == Count );

	TEST_OK( JpfsvSetTracePointsContext(
		NpCtx,
		JpfsvAddTracepoint,
		Set.Count,
		Set.Procedures,
		&FailedProc ) );
	// again - should be a noop.
	TEST_OK( JpfsvSetTracePointsContext(
		NpCtx,
		JpfsvAddTracepoint,
		Set.Count,
		Set.Procedures,
		&FailedProc ) );
	TEST( FailedProc == 0 );

	TEST_OK( JpfsvCountTracePointsContext( NpCtx, &Tracepoints ) );
	TEST( Tracepoints > Set.Count / 2 );	// Duplicate-cleaned!
	TEST( Tracepoints <= Set.Count );

	TEST_OK( JpfsvGetTracepointContext( NpCtx, Set.Procedures[ 0 ], &Tracepnt ) );
	TEST( Tracepnt.Procedure == Set.Procedures[ 0 ] );
	TEST( wcslen( Tracepnt.SymbolName ) );
	TEST( wcslen( Tracepnt.ModuleName ) );

	TEST( JPFSV_E_TRACEPOINT_NOT_FOUND == JpfsvGetTracepointContext( NpCtx, 0xBA2, &Tracepnt ) );

	//
	// Count enum callbacks.
	//
	TEST_OK( JpfsvEnumTracePointsContext(
		NpCtx,
		CountTracepointsCallback,
		&EnumCount ) );
	TEST( EnumCount == Tracepoints );

	//
	// Pump a little...
	//
	Sleep( 2000 );

	//
	// Stop while tracing active -> implicitly revoke all tracepoints.
	//
	TEST_OK( JpfsvStopTraceContext( NpCtx, TRUE ) );
	TEST_OK( JpfsvCountTracePointsContext( NpCtx, &Count ) );
	TEST( 0 == Count );

	//
	// Trace again.
	//
	TEST_OK( JpfsvStartTraceContext(
		NpCtx,
		5,
		1024,
		DiagSession ) );
	TEST_OK( JpfsvSetTracePointsContext(
		NpCtx,
		JpfsvAddTracepoint,
		Set.Count,
		Set.Procedures,
		&FailedProc ) );
	TEST( FailedProc == 0 );

	TEST_OK( JpfsvCountTracePointsContext( NpCtx, &Count ) );
	TEST( Tracepoints == Count );

	//
	// Pump a little...
	//
	Sleep( 2000 );

	//
	// Clean shutdown.
	//
	TEST_OK( JpfsvSetTracePointsContext(
		NpCtx,
		JpfsvRemoveTracepoint,
		Set.Count,
		Set.Procedures,
		&FailedProc ) );
	TEST( FailedProc == 0 );

	TEST_OK( JpfsvCountTracePointsContext( NpCtx, &Count ) );
	TEST( 0 == Count );

	TEST_OK( JpfsvStopTraceContext( NpCtx, TRUE ) );
	TEST_OK( DetachContextSafe( NpCtx ) );
	TEST_OK( JpfsvUnloadContext( NpCtx ) );

	TEST_OK( CdiagDereferenceSession( DiagSession ) );

	//
	// Kill notepad.
	//
	TEST( TerminateProcess( pi.hProcess, 0 ) );
	CloseHandle( pi.hProcess );
	CloseHandle( pi.hThread );

	//
	// Wait i.o. not to confuse further tests with dying process.
	//
	Sleep( 1000 );
}
예제 #26
0
ULONG	getSymbols()
{
	CString FilePathName;
	PCSTR path;
	DWORD error;
	DWORD64 dw64Base;
	DWORD dwFileSize;
	g_CountOfFunFound	=	0;
	dw64Base = getNtBase();
	if (dw64Base==0)
	{
		::MessageBox(NULL,"Get base 0",NULL,NULL);
		return 0 ;
	}
	char	szSystemDir[1024]={0};
	GetSystemDirectory(szSystemDir, sizeof(szSystemDir));
	FilePathName	=	szSystemDir;
	FilePathName	=	FilePathName+"\\"+PathFindFileName(osname);
	
	path=FilePathName;
	//记得要带上symsrv.dll和dbghelp.dll
	char *pSymPath	=	"srv*C:\\winddk\\symbolsl*http://msdl.microsoft.com/download/symbols";
	myprint("retriving symbols for %s,symbols store in %s\r\n",path, pSymPath);
	 SymCleanup(GetCurrentProcess());
	if (SymInitialize(GetCurrentProcess(), pSymPath, TRUE))
	{
		// SymInitialize returned success
	}
	else
	{
		// SymInitialize failed
		error = GetLastError();
		myprint("SymInitialize returned error : %d\n", error);
		return 0;
	}
	
	DWORD err=0;
	// get the file size
	HANDLE hFile = CreateFile( FilePathName, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
	if( INVALID_HANDLE_VALUE == hFile )
	{
		err	=	GetLastError();
		::MessageBox(NULL,"out",NULL,NULL);
		return false;
	}
	if( INVALID_FILE_SIZE == ( dwFileSize = GetFileSize(hFile, NULL)) )
	{
		
	}
	CloseHandle(hFile);
	
	
	DWORD64 dw64ModAddress=SymLoadModule64( GetCurrentProcess(),NULL, (char*)path,NULL,dw64Base,dwFileSize);
	
	if(dw64ModAddress==0)
	{
		error = GetLastError();
		myprint("SymLoadModule64 returned error : %d\n", error);
		return 0;
		
	}

	if(!SymEnumSymbols( GetCurrentProcess(),
		dw64ModAddress,
		NULL, // Null point out that list all symbols
		SymEnumSymbolsProc,
		NULL))
	{
		//_tprintf( _T("Failed when SymEnumSymbols(): %d \n"), GetLastError() );
		return 0;
	}
	myprint("g_CountOfFunFound %d\r\n", g_CountOfFunFound);
	bool bRetSym	=	(g_CountOfFunFound>sizeof(dync_funs)/sizeof(dync_funs[0]));
	return bRetSym?dw64Base:0;

}