示例#1
0
文件: CmdLog.cpp 项目: zzydog/OllyDog
HGLOBAL CCmdLog::CopyLog(int row)
{
	LPLOGGER plog = nullptr; int count = 0; int i;
	if (m_Table.mode & TABLE_STDSCR) {
		for (i = 0; ; ++i, count += plog->rows) {
			plog = reinterpret_cast<LPLOGGER> (
				Getsortedbyselection(&m_Table.sorted, i)
			);
			if (plog == nullptr) return nullptr;
			if (i != row) continue;
			m_Table.mode &= ~TABLE_STDSCR;
			HGLOBAL hMem = CopyRow(count, plog->rows);
			m_Table.mode |=  TABLE_STDSCR;
			return hMem;
		}
	} else {
		for (i = 0; ; ++i, count += plog->rows) {
			plog = reinterpret_cast<LPLOGGER> (
				Getsortedbyselection(&m_Table.sorted, i)
			);
			if (plog == nullptr) return nullptr;
			int end = count+static_cast<int>(plog->rows);
			if (row >= count && row < end) {
				return CopyRow(count, plog->rows);
			}
		}
	}
	// It should not be run here ..
	return nullptr;
}
示例#2
0
// Custom table function of hitlist window. Here it is used only to process
// doubleclicks (custom message WM_USER_DBLCLK). This function is also called
// on WM_DESTROY, WM_CLOSE (by returning -1, you can prevent window from
// closing), WM_SIZE (custom tables only), WM_CHAR (only if TABLE_WANTCHAR is
// set) and different custom messages WM_USER_xxx (depending on table type).
// See documentation for details.
long HitlistSelfunc(t_table *pt,HWND hw,UINT msg,WPARAM wp,LPARAM lp) {
  t_hitlist * item;
  switch (msg) {
    case WM_USER_DBLCLK:               // Doubleclick
      // Get selection.
      item=(t_hitlist *)Getsortedbyselection(&(pt->sorted),pt->sorted.selected);
      // Follow address in CPU Disassembler pane. Actual address is added to
      // the history, so that user can easily return back to it.
      if (item!=NULL) Setcpu(0,item->index,0,0,0, CPU_ASMHIST|CPU_ASMCENTER|CPU_ASMFOCUS);
      return 1;
    default: break;
  };
  return 0;
};
LRESULT CALLBACK polybp_winproc(HWND hw,UINT msg,WPARAM wp,LPARAM lp) {

HMENU menu;
unsigned int i;
unsigned long retaddr;
t_polymorphicbreakpoint	*slt_breakpoint;
t_thread *pthread;

	switch (msg) {
		case WM_DESTROY:
		case WM_MOUSEMOVE:
		case WM_LBUTTONDOWN:
		case WM_LBUTTONDBLCLK:
		case WM_LBUTTONUP:
		case WM_RBUTTONDOWN:
		case WM_RBUTTONDBLCLK:
		case WM_HSCROLL:
		case WM_VSCROLL:
		case WM_TIMER:
		case WM_SYSKEYDOWN:
		case WM_USER_SCR:
		case WM_USER_VABS:
		case WM_USER_VREL:
		case WM_USER_VBYTE:
		case WM_USER_STS:
		case WM_USER_CNTS:
		case WM_USER_CHGS:
		case WM_WINDOWPOSCHANGED:
			return olly_table_function(&breakpoint,hw,msg,wp,lp);

		case WM_USER_MENU:

			slt_breakpoint=(t_polymorphicbreakpoint *)olly_get_sorted_by_selection(&(breakpoint.data),breakpoint.data.selected);
			menu=olly_create_popup_menu();

			if (menu != 0 && slt_breakpoint != 0) {

				olly_append_menu(menu,MF_STRING,1,"Follow\tEnter");
				olly_append_menu(menu,MF_STRING,2,"Disable\tDel");

				i = olly_table_function(&breakpoint,hw,WM_USER_MENU,0,(LPARAM)menu);

					if (menu != 0) DestroyMenu(menu);

					if(i==1) olly_set_cpu(0,slt_breakpoint->addr,0,0,CPU_ASMHIST|CPU_ASMCENTER|CPU_ASMFOCUS);

					if(i==2) {
						/* Remove a PolyMorphic Breakpoint */

						if((slt_breakpoint->able == 1) && (ispaused == 1)) {
								
							switch(slt_breakpoint->type) {

							case 0:
								pthread=olly_find_thread(olly_get_cpu_thread_id());
								context = pthread->context;
								
								if((context.Eip >= slt_breakpoint->addr+4) && (context.Eip < slt_breakpoint->addr + 12)) {
									
									// Ajust esp
									context.Esp += 4;
									pthread->reg.r[4] += 4;
									// Restore eip
									context.Eip = slt_breakpoint->addr;
									pthread->reg.ip = slt_breakpoint->addr;
									

								}
									// Delete
									DisableBreakpoint(slt_breakpoint);
							break;
							
							case 1:
								pthread=olly_find_thread(olly_get_cpu_thread_id());
								context = pthread->context;
								
								if((context.Eip >= slt_breakpoint->addr+4) && (context.Eip < slt_breakpoint->addr + 17)) {

									// Ajust esp
									context.Esp += 4;
									pthread->reg.r[4] += 4;
									// Restore eip
									context.Eip = slt_breakpoint->addr;
									pthread->reg.ip = slt_breakpoint->addr;

								}
									// Delete
									DisableBreakpoint(slt_breakpoint);

							break;

							case 2:
								
									// Delete
									DisableBreakpoint(slt_breakpoint);

							break;

							case 3:
								pthread=olly_find_thread(olly_get_cpu_thread_id());
								context = pthread->context;

								if((context.Eip >= slt_breakpoint->addr+4) && (context.Eip < slt_breakpoint->addr + 15)) {

									// Ajust esp
									context.Esp += 4;
									pthread->reg.r[4] += 4;
									// Restore eip
									pthread->reg.ip = slt_breakpoint->addr;
									context.Eip = slt_breakpoint->addr;


								}
								else if(context.Eip == context.Esp) {

									if(Readmemory(&retaddr,pthread->reg.r[4]+2,4,MM_RESILENT) == 0) {
										olly_add_to_list(0, __ERROR__, "[Error at %x08X] Can't read the memory.", pthread->reg.r[4]+2);
										break;
									}
									if(retaddr == slt_breakpoint->addr+5) {

									// Ajust esp
									context.Esp += 6;
									pthread->reg.r[4] += 6;
									// Restore eip
									pthread->reg.ip = slt_breakpoint->addr;
									context.Eip = slt_breakpoint->addr;

									}

								}
									// Delete
									DisableBreakpoint(slt_breakpoint);
							break;

							} // switch(slt_breakpoint->type)
						} // pause

					} // ifremove

				InvalidateRect(hw,NULL,FALSE);

		}
		return 0;

		case WM_USER_DBLCLK:
			slt_breakpoint=(t_polymorphicbreakpoint *)olly_get_sorted_by_selection(
				&(breakpoint.data),breakpoint.data.selected);
				if(slt_breakpoint != 0)
					olly_set_cpu(0,slt_breakpoint->addr,0,0,CPU_ASMHIST|CPU_ASMCENTER|CPU_ASMFOCUS);
		return 0;

		case WM_KEYDOWN:
			if (wp==VK_RETURN && (GetKeyState(VK_SHIFT) & 0x8000)==0 && (GetKeyState(VK_CONTROL) & 0x8000)==0) {
				slt_breakpoint=(t_polymorphicbreakpoint *)Getsortedbyselection(
						&(breakpoint.data),breakpoint.data.selected);
						if(slt_breakpoint!=NULL)
							olly_set_cpu(0,slt_breakpoint->addr,0,0,CPU_ASMHIST|CPU_ASMCENTER|CPU_ASMFOCUS);
			}
		return 0;

        case WM_USER_CHALL:
        case WM_USER_CHMEM:
            InvalidateRect(hw, NULL, FALSE);
            return 0;
        case WM_PAINT:
            olly_paint_table(hw, &breakpoint, polybp_get_text);
		return 0;

		default:
		break;
	}

	return DefMDIChildProc(hw,msg,wp,lp);
}
示例#4
0
文件: CmdLog.cpp 项目: zzydog/OllyDog
// If column is DF_CACHESIZE, this function must return the requested 
// size of the data cache. If column is DF_FILLCACHE, DF_FREECACHE or 
// DF_NEWROW, it must return 0. In all other cases, it must return the 
// length of the displayed string s in wide characters (and, if mask is 
// used, the length of the mask in bytes)
int  CCmdLog::DrawProc(
	wchar* str, uchar* mask, int* select, t_table* table, 
	t_sorthdr* sort, int column, void* cache
) {
	static wchar * cmdtype[] = {	// Command types we supported .
		text("unknow"),
		text("bat"), text("lua"), 
		text("java"), text("perl"), text("ruby"), text("tool"), 
		text("inline"), text("python"), text("system"), text("multicmd")
	};
	//
	// Note: 
	// For table with style TABLE_SIMPLE or TABLE_USERDEF,
	// "t_sorthdr *sort" is the pointer to the index of drawing loop.
	//
	LPLOGGER plog;
	std::wstring *pmsg; 
	std::vector<t_sorthdr> *rows;
	int len, color, max = TEXTLEN * 2;
	ulong irow = sort->addr + table->offset;
	t_sorthdr* thdr = reinterpret_cast<t_sorthdr*>(cache);
	t_sorthdr* msge = reinterpret_cast<t_sorthdr*>(&thdr[1]);
	LPLOGGER logger = reinterpret_cast<LPLOGGER>(&msge[1]);

	// The logger can't be null while drawing ..
	if (column > DF_NEWROW && logger == nullptr) return 0;
	if (column > DF_NEWROW && logger->addr == 0) return 0;

	// The common mask flag .
	if (irow == table->sorted.selected) *select |= DRAW_SELECT;
	*select |= DRAW_MASK|DRAW_NEW|DRAW_EXTSEL|DRAW_COLOR;

	switch (column) {
	case DF_CACHESIZE:				// Request for draw cache size
		// We require cache for outputing.
		//-----------------------------------------------------
		//ulong		addr;	// std::vector<t_sorthdr> *
		//ulong		size;	// The row count of handled logger
		//ulong		type;	// The selection index ..
		//-----------------------------------------------------
		//ulong		addr;	// The string offset .
		//ulong		size;	// The size of this string buffer
		//ulong		type;	// The 0-based index of this line
		//-----------------------------------------------------
		//ulong		addr;	// Nothing changed .
		//ulong		size;	// Nothing changed .
		//ulong		type;	// Nothing changed .
		//ulong		rows;	// Nothing changed .
		//time_t		time;	// Nothing changed .
		//long			code;	// Nothing changed .
		//void*		msge;	// The splited multiline array .
		return sizeof(t_sorthdr)+sizeof(t_sorthdr)+sizeof(LOGGER);

	case DF_FILLCACHE:				// Request to fill draw cache
		// Now we need to initialize cache when drawing begins.
		max = sizeof(t_sorthdr)+sizeof(t_sorthdr)+sizeof(LOGGER);
		memset_s(cache, max, 0, max);		// Zero the cache ..
		// Needn't allocate the array if it uses single line ..
		if (table->mode & TABLE_STDSCR) ;
		else rows = new std::vector<t_sorthdr>;
		thdr->addr = reinterpret_cast<ulong>(rows);
		return 0;

	case DF_FREECACHE:				// Request to free cached resources
		// We need to free cached resources when drawing ends.
		rows = reinterpret_cast<std::vector<t_sorthdr>*>(thdr->addr);
		if (table->mode & TABLE_STDSCR) ;
		else if (rows != nullptr) delete rows;
		return 0;

	case DF_NEWROW:					// Request to start new row in window
		//
		// ---------------> For single line drawing ..
		//
		if (table->mode & TABLE_STDSCR) {
			plog = reinterpret_cast<LPLOGGER>(
				Getsortedbyselection(&table->sorted, irow)
			);
			if (plog != nullptr && plog->addr != 0) {
				*logger = *plog; thdr->size = irow; 
				pmsg = reinterpret_cast<std::wstring*>(plog->msge);
				msge->addr = msge->type = 0;
				msge->size = pmsg->find_first_of(text('\n'));
				if (msge->size == std::wstring::npos)
					msge->size = pmsg->length();
			} else logger->addr = 0;	// Return a null logger .
			return 0;	// Finish ....
		}

		//
		// ---------------> For multi-line drawing ..
		//
		// Find the logger by the row number ..
		for (plog = logger; irow >= thdr->size + plog->rows; ) {
			thdr->size += plog->rows; // Goto the next level.
			plog = reinterpret_cast<LPLOGGER>(
				Getsortedbyselection(&table->sorted,thdr->type++)
			);
			// Already output all loggers or it's a invalid logger
			if (!plog || !plog->addr) { logger->addr = 0; return 0; }
		}
		// Get the row list ..
		rows = reinterpret_cast<std::vector<t_sorthdr>*>(thdr->addr);
		// Save this logger to the cache if it's new ..
		if (plog != nullptr && plog != logger && plog->addr) {
			// Copy as a new logger cache and clear old logger rows.
			*logger = *plog; rows->clear();
			// Now parsing message information ..
			msge->addr = msge->size = msge->type = 0;
			pmsg = reinterpret_cast<std::wstring*>(plog->msge);
			std::wstring::const_iterator npos, nend = pmsg->cend();
			for (npos = pmsg->cbegin(); npos != nend; ++npos) {
				if (*npos == TEXT('\n')) {	// The line ending ..
					msge->type  = rows->size(); rows->push_back(*msge);
					msge->addr += msge->size+1; msge->size = 0;
				} else ++msge->size;			// The normal chars ..
			} if (pmsg->back() != text('\n')) {
				msge->type  = rows->size(); rows->push_back(*msge);
			} while (rows->size() < plog->rows) {
				msge->type = rows->size(); msge->size = 0;
				rows->push_back(*msge);		// Insert null logger .
			}
		}
		// Now, get the target row and put it into the cache .
		msge->type = irow-thdr->size; *msge = rows->at(msge->type);
		return 0;
		
	case 0:							// The number of logging item .
		// Do nothing if it's not the first line .
		if (irow > thdr->size) return 0;
		len = ::swprintf_s(str, max, TEXT("%d"), logger->addr);
		memset_s(mask, max, DRAW_GRAY, len);
		break;
	case 1:							// The time when logging happen.
		struct tm stm; localtime_s(&stm, &logger->time);
		len = ::wcsftime(str, max, TEXT("%I:%M:%S %p"), &stm);
		memset_s(mask, max, DRAW_NORMAL, len);
		break;
	case 2:							// The cmd type of execution .
		// Do nothing if it's not the first line .
		if (irow > thdr->size) return 0;
		if (logger->type >= _countof(cmdtype)) break;
		len = ::wcsnlen_s(cmdtype[logger->type], 10);
		::wcsncpy_s(str, max, cmdtype[logger->type], 10);
		color = logger->code == 0 ? DRAW_NORMAL : DRAW_HILITE;
		memset_s(mask, max, color, len);
		break;
	case 3:							// The error code of execution .
		// Do nothing if it's not the first line .
		if (irow > thdr->size) return 0;
		len = ::swprintf_s(str, max, TEXT("%i"), logger->code);
		color = logger->code == 0 ? DRAW_NORMAL : DRAW_HILITE;
		memset_s(mask, max, color, len);
		break;
	case 4:							// The answer of execution .
		pmsg = reinterpret_cast<std::wstring*>(logger->msge);
		// Get the color ...
		color = logger->code == 0 ? DRAW_NORMAL : DRAW_HILITE;
		// For the single line, need to add G_SINGLE.
		if (logger->rows == 1) {
			color = DRAW_HILITE;	// Always highlight the first line
			*str++ = G_CALLDEST; *mask++ = DRAW_GRAPH; --max;
			*str++ = G_CALLDEST; *mask++ = DRAW_GRAPH; --max;
		// For multi-line, but doesn't support multi-line outputing
		} else if (table->mode & TABLE_STDSCR) {
			color = DRAW_HILITE;	// Always highlight the first line
			*str++ = G_SINGLE; *mask++ = DRAW_GRAPH; --max;
			*str++ = G_CALLDEST; *mask++ = DRAW_GRAPH; --max;
		// For the first line, need to add G_BEGIN ..
		} else if (msge->type == 0) {
			color = DRAW_HILITE;	// Always highlight the first line
			*str++ = G_BEGIN; *mask++ = DRAW_GRAPH; --max;
			*str++ = G_CALLDEST; *mask++ = DRAW_GRAPH; --max;
		// For the last line, need to add G_END ..
		} else if (msge->type+1 >= logger->rows) {
			//*str++ = msge->size == 0 ? G_END : G_ENTRY;
			*str++ = G_END;   *mask++ = DRAW_GRAPH; --max;
			*str++ = G_POINT; *mask++ = DRAW_GRAPH; --max;
			*str++ = G_SPACE; *mask++ = DRAW_GRAPH; --max;
			*str++ = G_SPACE; *mask++ = DRAW_GRAPH; --max;
		// For the body line  ...
		} else {
			*str++ = msge->size == 0 ? G_BODY : G_ENTRY;
			*mask++ = DRAW_GRAPH; --max;
			*str++ = G_POINT; *mask++ = DRAW_GRAPH; --max;
			*str++ = G_SPACE; *mask++ = DRAW_GRAPH; --max;
			*str++ = G_SPACE; *mask++ = DRAW_GRAPH; --max;
		}
		*str++ = G_SPACE; *mask++ = DRAW_GRAPH; --max;
		::wcsncpy_s(str, max, pmsg->c_str()+msge->addr, msge->size);
		memset_s(mask, max, color, msge->size);
		len = msge->size + TEXTLEN * 2 - max;
		break;
	default: return 0;
	}
	return len;			// Return the length of the text ..
}
示例#5
0
// Each window class needs its own window procedure. Both standard and custom
// OllyDbg windows must pass some system and OllyDbg-defined messages to
// Tablefunction(). See description of Tablefunction() for more details.
LRESULT CALLBACK Bookmarkwinproc(HWND hw, UINT msg, WPARAM wp, LPARAM lp)
{
	int i, shiftkey, controlkey;
	HMENU menu;
	t_bookmark *pb;
	switch (msg)
	{
		// Standard messages. You can process them, but - unless absolutely sure -
		// always pass them to Tablefunction().
	case WM_DESTROY:
	case WM_MOUSEMOVE:
	case WM_LBUTTONDOWN:
	case WM_LBUTTONDBLCLK:
	case WM_LBUTTONUP:
	case WM_RBUTTONDOWN:
	case WM_RBUTTONDBLCLK:
	case WM_HSCROLL:
	case WM_VSCROLL:
	case WM_TIMER:
	case WM_SYSKEYDOWN:
		Tablefunction(&bookmark, hw, msg, wp, lp);
		break;                           // Pass message to DefMDIChildProc()
		// Custom messages responsible for scrolling and selection. User-drawn
		// windows must process them, standard OllyDbg windows without extra
		// functionality pass them to Tablefunction().
	case WM_USER_SCR:
	case WM_USER_VABS:
	case WM_USER_VREL:
	case WM_USER_VBYTE:
	case WM_USER_STS:
	case WM_USER_CNTS:
	case WM_USER_CHGS:
		return Tablefunction(&bookmark, hw, msg, wp, lp);
		// WM_WINDOWPOSCHANGED is responsible for always-on-top MDI windows.
	case WM_WINDOWPOSCHANGED:
		return Tablefunction(&bookmark, hw, msg, wp, lp);
	case WM_USER_MENU:
		menu = CreatePopupMenu();
		// Find selected bookmark. Any operations with bookmarks make sense only
		// if at least one bookmark exists and is selected. Note that sorted data
		// has special sort index table which is updated only when necessary.
		// Getsortedbyselection() does this; some other sorted data functions
		// don't and you must call Sortsorteddata(). Read documentation!
		pb = (t_bookmark *)Getsortedbyselection(
		         &(bookmark.data), bookmark.data.selected);
		if (menu != NULL && pb != NULL)
		{
			AppendMenu(menu, MF_STRING, 1, "&Follow\tEnter");
			AppendMenu(menu, MF_STRING, 2, "&Delete\tDel");
		};
		// Even when menu is NULL, call to Tablefunction is still meaningful.
		i = Tablefunction(&bookmark, hw, WM_USER_MENU, 0, (LPARAM)menu);
		if (menu != NULL) DestroyMenu(menu);
		if (i == 1)                      // Follow bookmark in Disassembler
			Setcpu(0, pb->addr, 0, 0, CPU_ASMHIST | CPU_ASMCENTER | CPU_ASMFOCUS);
		else if (i == 2)                 // Delete bookmark
		{
			Deletesorteddata(&(bookmark.data), pb->index);
			// There is no automatical window update, do it yourself.
			InvalidateRect(hw, NULL, FALSE);
		};
		return 0;
	case WM_KEYDOWN:
		// Processing of WM_KEYDOWN messages is - surprise, surprise - very
		// similar to that of corresponding menu entries.
		shiftkey = GetKeyState(VK_SHIFT) & 0x8000;
		controlkey = GetKeyState(VK_CONTROL) & 0x8000;
		if (wp == VK_RETURN && shiftkey == 0 && controlkey == 0)
		{
			// Return key follows bookmark in Disassembler.
			pb = (t_bookmark *)Getsortedbyselection(
			         &(bookmark.data), bookmark.data.selected);
			if (pb != NULL)
				Setcpu(0, pb->addr, 0, 0, CPU_ASMHIST | CPU_ASMCENTER | CPU_ASMFOCUS);
			;
		}
		else if (wp == VK_DELETE && shiftkey == 0 && controlkey == 0)
		{
			// DEL key deletes bookmark.
			pb = (t_bookmark *)Getsortedbyselection(
			         &(bookmark.data), bookmark.data.selected);
			if (pb != NULL)
			{
				Deletesorteddata(&(bookmark.data), pb->index);
				InvalidateRect(hw, NULL, FALSE);
			};
		}
		else
			// Add all this arrow, home and pageup functionality.
			Tablefunction(&bookmark, hw, msg, wp, lp);
		break;
	case WM_USER_DBLCLK:
		// Doubleclicking row follows bookmark in Disassembler.
		pb = (t_bookmark *)Getsortedbyselection(
		         &(bookmark.data), bookmark.data.selected);
		if (pb != NULL)
			Setcpu(0, pb->addr, 0, 0, CPU_ASMHIST | CPU_ASMCENTER | CPU_ASMFOCUS);
		return 1;                        // Doubleclick processed
	case WM_USER_CHALL:
	case WM_USER_CHMEM:
		// Something is changed, redraw window.
		InvalidateRect(hw, NULL, FALSE);
		return 0;
	case WM_PAINT:
		// Painting of all OllyDbg windows is done by Painttable(). Make custom
		// drawing only if you have important reasons to do this.
		Painttable(hw, &bookmark, Bookmarkgettext);
		return 0;
	default:
		break;
	};
	return DefMDIChildProc(hw, msg, wp, lp);
};