Esempio n. 1
0
void dump_scopetable_entry (struct MemoryCache *mc, struct process *p, int i, address a)
{
	bool b;
	struct my_SCOPETABLE_ENTRY e;

	b=MC_ReadBuffer (mc, a, sizeof(struct my_SCOPETABLE_ENTRY), (BYTE*)&e);
	if (b==false)
	{
		L ("%s() cannot read scopetable entry\n", __FUNCTION__);
		return;
	};
	strbuf sb2=STRBUF_INIT;
	process_get_sym (p, e.handler, true /* add_module_name */, true /* add_offset */, &sb2);
	if (e.filter)
	{
		strbuf sb1=STRBUF_INIT;
		process_get_sym (p, e.filter, true /* add_module_name */, true /* add_offset */, &sb1);
		L ("scopetable entry[%d]. previous try level=%d, filter=0x" PRI_ADR_HEX 
				" (%s) handler=0x" PRI_ADR_HEX " (%s)\n", i, e.previousTryLevel, 
				e.filter, sb1.buf,
				e.handler, sb2.buf);
		strbuf_deinit(&sb1);
	}
	else
		L ("scopetable entry[%d]. previous try level=%d, finally=0x" PRI_ADR_HEX " (%s)\n", 
				i, e.previousTryLevel, 
				e.handler, sb2.buf);
	strbuf_deinit(&sb2);
};
Esempio n. 2
0
void enum_files_in_dir(const char* path, callback_fn cb, void *param)
{
	assert(path);
#ifdef _WIN32
	strbuf tmp=STRBUF_INIT;
	strbuf_addf (&tmp, "%s\\*", path);
	struct _finddata_t d;
	int fh=_findfirst(tmp.buf, &d);
	assert(fh!=-1);
	strbuf tmp2=STRBUF_INIT;

	do
	{
		if (strcasecmp(d.name, ".")==0)
			continue;
		
		strbuf_reinit(&tmp2, 0);
		strbuf_addf (&tmp2, "%s\\%s", path, d.name);

		cb (d.name, tmp2.buf, d.size, d.time_write, IS_SET(d.attrib, _A_SUBDIR), param);

	} while (_findnext(fh, &d)==0);

	_findclose (fh);
	strbuf_deinit(&tmp2);
	strbuf_deinit (&tmp);
#elif defined(__linux__) || defined(__CYGWIN__) || defined (__APPLE__)
	DIR* DIR_V = opendir(path);
	struct dirent* t = NULL;
	if (DIR_V==NULL)
		die ("opendir(%s) failed: %s\n", path, strerror(errno));

	strbuf tmp2=STRBUF_INIT;

	while ((t=readdir(DIR_V))!=NULL)
	{
		if (strcasecmp(t->d_name, ".")==0)
			continue;
		
		strbuf_reinit(&tmp2, 0);
		strbuf_addf (&tmp2, "%s/%s", path, t->d_name);
		struct stat st;
		if (stat (tmp2.buf, &st)==-1)
			die ("stat(%s) failed: %s\n", tmp2.buf, strerror(errno));
// conflict with c99...
#ifndef DT_DIR
#define DT_DIR 4
#endif
		cb (t->d_name, tmp2.buf, st.st_size, st.st_mtime, IS_SET(t->d_type, DT_DIR), param);
	};
	
	strbuf_deinit(&tmp2);
	closedir(DIR_V);
#else
#warning "undetermined compiler"
#endif
};
Esempio n. 3
0
void add_symbol (address a, char *name, add_symbol_params *params)
{
    module *m=params->m;
    rbtree *symtbl=m->symbols;
    oassert(symtbl && "symbols=NULL in module");
    MemoryCache *mc=params->mc;

    if (one_time_int3_bp_re && params->t==SYM_TYPE_PE_EXPORT && module_adr_in_executable_section (m, a))
    {
        strbuf sb=STRBUF_INIT;
        strbuf_addstr (&sb, get_module_name(m));
        strbuf_addc (&sb, '!');
        strbuf_addstr (&sb, name);

        if (regexec (one_time_int3_bp_re, sb.buf, 0, NULL, 0)==0)
            set_onetime_INT3_BP(a, params->p, m, name, mc);

        strbuf_deinit (&sb);
    };

    if (dump_seh && string_is_ends_with (name, "security_cookie"))
    {
        m->security_cookie_adr=a;
        m->security_cookie_adr_known=true;
        if (symbol_c_debug)
            L ("%s() got address of security_cookie (0x" PRI_REG_HEX ") for %s!%s\n", __FUNCTION__, a, get_module_name(m), name);
    };

    bool dump_symbol=false;
    if (dump_all_symbols_re)
    {
        strbuf sb=STRBUF_INIT;
        strbuf_addstr (&sb, get_module_name(m));
        strbuf_addc (&sb, '!');
        strbuf_addstr (&sb, name);

        if (regexec (dump_all_symbols_re, sb.buf, 0, NULL, 0)==0)
            dump_symbol=true;

        strbuf_deinit (&sb);
    };

    if (dump_symbol || (dump_all_symbols_re==NULL && dump_all_symbols))
    {
        dump_PID_if_need(params->p);
        L("New symbol. Module=[%s], address=[0x" PRI_ADR_HEX "], name=[%s]\n", get_module_name(m), a, name);
    };

    symbol *new_sym=create_symbol(params->t, name);
    symbol *first_sym=(symbol*)rbtree_lookup(symtbl, (void*)a);

    if (first_sym)
        new_sym->next=first_sym; // insert at beginning of list

    rbtree_insert(symtbl, (void*)a, (void*)new_sym);
};
Esempio n. 4
0
static void dump_stack_not_using_EBP (process *p, thread *t, CONTEXT *ctx, MemoryCache *mc)
{
    HANDLE THDL=t->THDL;
    address stack_top=TIB_get_stack_top (THDL, mc);
    address stack_bottom=TIB_get_stack_bottom (THDL, mc);
    //strbuf sb=STRBUF_INIT;
    address SP_at_start=CONTEXT_get_SP(ctx);

    L ("Call stack:\n");
 
    if (thread_c_debug)
        L ("SP_at_start=0x%x, stack_top=0x%x, stack_bottom=0x%x\n", SP_at_start, stack_top, stack_bottom);

    for (address a=SP_at_start; a<stack_top; a=a+sizeof(REG))
    {
        REG r;
        if (MC_ReadREG(mc, a, &r))
        {
            //L ("r=0x" PRI_REG_HEX "\n", r);
            if (adr_in_executable_section(p, r))
            {
                strbuf sb=STRBUF_INIT;
                process_get_sym (p, r, true, true, &sb);
                L ("(SP+0x%x) return address=0x" PRI_ADR_HEX " (%s)\n", a-SP_at_start, r, sb.buf);
                strbuf_deinit(&sb);
            };
        };
    };
};
Esempio n. 5
0
static void dump_stack_EBP_frame (process *p, thread *t, CONTEXT * ctx, MemoryCache *mem)
{
    HANDLE THDL=t->THDL;
    address stack_top=TIB_get_stack_top (THDL, mem);
    address stack_bottom=TIB_get_stack_bottom (THDL, mem);
    strbuf sb=STRBUF_INIT;

    L ("Call stack:\n");

    address next_BP=CONTEXT_get_BP (ctx);

    if (TIB_is_ptr_in_stack_limits (THDL, next_BP, mem)==false)
    {
        L ("Current frame pointer %s (0x" PRI_ADR_HEX ") is not within current stack limits (top=0x" PRI_ADR_HEX ", bottom=0x" PRI_ADR_HEX ")\n", 
                BP_REGISTER_NAME,
                CONTEXT_get_BP (ctx), stack_top, stack_bottom);
        goto exit;
    };

    while (next_BP<=stack_top && next_BP>=stack_bottom)
    {
        REG tmp;
        bool b=MC_ReadREG(mem, next_BP, &tmp);
        oassert (b);
        address ret_adr;
        b=MC_ReadREG(mem, next_BP+sizeof(REG), &ret_adr);
        oassert (b);

        if (ret_adr==0)
            break;

        strbuf_reinit(&sb, 0);
        process_get_sym (p, ret_adr, true, true, &sb);

        L ("return address=0x" PRI_ADR_HEX " (%s)\n", ret_adr, sb.buf);

        if (next_BP==tmp)
            break;
        
        next_BP=tmp;
    };

exit:
    strbuf_deinit (&sb);
};
Esempio n. 6
0
void dump_buf_as_array_of_strings(MemoryCache *mc, address a, size_t size)
{
    strbuf sb=STRBUF_INIT;
    BYTE *buf=DMALLOC (BYTE, size, "BYTE*");
    if (MC_ReadBuffer (mc, a, size, buf)==false)
        goto exit;
    for (unsigned i=0; i<size; i+=sizeof(REG))
    {
        address a2=*(REG*)&buf[i];
        if (MC_get_any_string(mc, a2, &sb))
        {
            L ("0x" PRI_ADR_HEX "+0x%x: ptr to %s\n", a, i, sb.buf);
            strbuf_reinit(&sb, 0);
        };
    };
exit:
    DFREE (buf);
    strbuf_deinit(&sb);
};
Esempio n. 7
0
// replace %substring% to environment variable, if possible
void env_vars_expansion(strbuf *sb, char** env)
{
	oassert(env!=NULL);
	for (int i=0; env[i]; i++)
	{
		char *s=DSTRDUP (env[i], "env");
		char *s1=strtok (s, "=");
		char *s2=strtok (NULL, "=");
		strbuf percented_env_var=STRBUF_INIT;
		strbuf_addc (&percented_env_var, '%');
		strbuf_addstr (&percented_env_var, s1);
		strbuf_addc (&percented_env_var, '%');

		strbuf_replace_if_possible (sb, percented_env_var.buf, s2);

		strbuf_deinit(&percented_env_var);
		DFREE(s);
	};
};
Esempio n. 8
0
// FIXME: find another place for this function
void set_or_update_DRx_breakpoint(BP *bp, CONTEXT *ctx, unsigned DRx_no)
{
    oassert (bp->a->resolved);
    if (utils_c_debug)
    {
        strbuf sb=STRBUF_INIT;
        address_to_string(bp->a, &sb);
        L ("%s(): begin. setting DRx-breakpoint %d for %s at 0x" PRI_ADR_HEX "\n", 
                __func__, DRx_no, sb.buf, bp->a->abs_address);
        strbuf_deinit (&sb);
    };

    if (bp->t==BP_type_BPF || bp->t==BP_type_BPX)
        CONTEXT_setDRx_and_DR7 (ctx, DRx_no, bp->a->abs_address);
    else if (bp->t==BP_type_BPM)
        BPM_set_or_update_DRx_breakpoint(bp->u.bpm, bp->a->abs_address, DRx_no, ctx);
    else
    {
        oassert(0);
        fatal_error();
    };
    if (utils_c_debug)
        L ("%s() end\n", __func__);
};
Esempio n. 9
0
// returns address of next SEH frame
address dump_SEH_frame (fds* s, struct process* p, struct thread* t, struct MemoryCache *mc, address a)
{
	struct my_EXCEPTION_REGISTRATION current_SEH_frame;
	bool b;

	b=MC_ReadBuffer (mc, a, 
			sizeof(struct my_EXCEPTION_REGISTRATION), (BYTE*)&current_SEH_frame);
	if (b==false)
	{
		L ("%s() cannot read current SEH frame\n", __FUNCTION__);
		return REG_MAX;
	};

	strbuf sb=STRBUF_INIT;
	process_get_sym (p, current_SEH_frame.handler, true /* add_module_name */, true /* add_offset */, &sb);

	L ("* SEH frame at 0x" PRI_ADR_HEX " prev=0x" PRI_ADR_HEX " handler=0x" PRI_ADR_HEX " (%s)\n", 
			a, current_SEH_frame.prev, current_SEH_frame.handler, sb.buf);

	bool SEH3=false, SEH4=false;

	if (string_is_ends_with (sb.buf, "except_handler3"))
		SEH3=true;

	REG security_cookie;
	bool security_cookie_known=false;
	if (string_is_ends_with (sb.buf, "except_handler4"))
	{
		SEH4=true;
		struct module *m=find_module_for_address(p, current_SEH_frame.handler);
		if (m->security_cookie_adr_known)
		{
			b=MC_ReadREG (mc, m->security_cookie_adr, &security_cookie);
			if (b==false)
				L ("%s() can't read security_cookie at 0x" PRI_ADR_HEX " for %s\n", 
						__FUNCTION__, m->security_cookie_adr, get_module_name (m));
			else
				security_cookie_known=true;
		}
		else
		{
			L ("SEH4 frame is here, but address of security_cookie is not known\n");
			L ("Try to place .PDB or .MAP file here with this symbol in it\n");
		};
	};

	if (SEH3==false && SEH4==false)
		goto exit;

	struct my_VC_EXCEPTION_REGISTRATION_RECORD current_SEH3_frame;
	b=MC_ReadBuffer (mc, a,
			sizeof(struct my_VC_EXCEPTION_REGISTRATION_RECORD), (BYTE*)&current_SEH3_frame);
	if (b==false)
	{
		L ("%s() cannot read current SEH3/4 frame\n", __FUNCTION__);
		return REG_MAX;
	};

	int previous_trylevel=current_SEH3_frame.previous_trylevel;
	L ("SEH%d frame. previous trylevel=%d\n", SEH3 ? 3 : 4, previous_trylevel);
	address scopetable_address=current_SEH3_frame.scopetable;
	if (SEH4 && security_cookie_known)
	{
		scopetable_address^=security_cookie;
		struct my_EH4_SCOPETABLE_HEADER EH4_header;
		b=MC_ReadBuffer (mc, scopetable_address,
				sizeof(struct my_EH4_SCOPETABLE_HEADER), (BYTE*)&EH4_header);
		if (b==false)
		{
			L ("%s() cannot read current SEH4 frame header. scopetable_address=0x" PRI_ADR_HEX "\n", 
					__FUNCTION__, scopetable_address);
			return REG_MAX;
		};
		L ("SEH4 header:\tGSCookieOffset=0x%x GSCookieXOROffset=0x%x\n", EH4_header.GSCookieOffset, EH4_header.GSCookieXOROffset);
		L ("\t\tEHCookieOffset=0x%x EHCookieXOROffset=0x%x\n", EH4_header.EHCookieOffset, EH4_header.EHCookieXOROffset);

		unsigned adr_of_EBP=a + ((byte*)&current_SEH3_frame.EBP - (byte*)&current_SEH3_frame.prev);

		if (EH4_header.EHCookieOffset!=-2)
			check_SEH4_cookie (mc, adr_of_EBP, EH4_header.EHCookieOffset, EH4_header.EHCookieXOROffset, security_cookie, "EH");
		if (EH4_header.GSCookieOffset!=-2)
			check_SEH4_cookie (mc, adr_of_EBP, EH4_header.GSCookieOffset, EH4_header.GSCookieXOROffset, security_cookie, "GS");

		scopetable_address+=sizeof(struct my_EH4_SCOPETABLE_HEADER);
	};
	if (previous_trylevel>=0 && (SEH3 || (SEH4 && security_cookie_known)))
		dump_scopetable(mc, p, scopetable_address, previous_trylevel+1);

exit:
	strbuf_deinit (&sb);
	return current_SEH_frame.prev;
};
Esempio n. 10
0
File: BPM.c Progetto: ohio813/tracer
void handle_BPM(process *p, thread *t, int bp_no, CONTEXT *ctx, MemoryCache *mc)
{
    BP *bp=breakpoints[bp_no];
    BPM *bpm=bp->u.bpm;

    address a=bp->a->abs_address;
    bool b;
    REG val;
    const char* v_type;

    switch (bpm->width)
    {
        case 1:
            {
                v_type="BYTE"; 
                byte tmp;
                b=MC_ReadByte (mc, a, &tmp);
                oassert(b);
                val=tmp;
            };
            break;

        case 2:
            {
                v_type="WORD"; 
                wyde tmp;
                b=MC_ReadWyde (mc, a, &tmp);
                oassert(b);
                val=tmp;
            };
            break;

        case 4:
            {
                v_type="DWORD"; 
                DWORD tmp;
                b=MC_ReadTetrabyte (mc, a, &tmp);
                oassert(b);
                val=tmp;
            };
            break;

        case 8:
            {
#ifdef _WIN64
                v_type="QWORD"; 
                DWORD64 tmp;
                b=MC_ReadOctabyte (mc, a, &tmp);
                oassert(b);
                val=tmp;
#else
                oassert (0);
#endif
            };
            break;

        default:
            oassert(0);
            fatal_error();
    };

    strbuf sb_sym=STRBUF_INIT, sb_bp_adr=STRBUF_INIT;
    address PC=CONTEXT_get_PC(ctx);
    process_get_sym (p, PC, true, true, &sb_sym);
    address_to_string(bp->a, &sb_bp_adr);

    dump_PID_if_need(p); dump_TID_if_need(p, t);
    L ("(%d) some code at %s (0x" PRI_ADR_HEX ") %s %s variable at %s (it contain 0x" PRI_REG_HEX 
            " after execution of that instruction)\n",
            bp_no, sb_sym.buf, PC, bpm->t==BPM_type_RW ? "reading or writting" : "writting", 
            v_type, sb_bp_adr.buf, val);

    //MC_WriteOctabyte(mc, bp->a->abs_address, 0); // can be option?
    
    strbuf_deinit(&sb_bp_adr);
    strbuf_deinit(&sb_sym);
};
Esempio n. 11
0
void strbuf_reinit(strbuf *sb, size_t size)
{
	strbuf_deinit (sb);
	strbuf_init (sb, size);
};