Пример #1
0
void CtrlDisAsmView::assembleOpcode(u32 address, std::string defaultText)
{
	u32 encoded;

	if (Core_IsStepping() == false) {
		MessageBox(wnd,L"Cannot change code while the core is running!",L"Error",MB_OK);
		return;
	}
	std::string op;
	bool result = InputBox_GetString(MainWindow::GetHInstance(),wnd,L"Assemble opcode",defaultText, op, false);
	if (!result)
		return;

	result = MIPSAsm::MipsAssembleOpcode(op.c_str(),debugger,address,encoded);
	if (result == true)
	{
		Memory::Write_U32(encoded, address);
		// In case this is a delay slot or combined instruction, clear cache above it too.
		if (MIPSComp::jit)
			MIPSComp::jit->ClearCacheAt(address - 4, 8);
		scanFunctions();
		redraw();
	} else {
		std::wstring error = ConvertUTF8ToWString(MIPSAsm::GetAssembleError());
		MessageBox(wnd,error.c_str(),L"Error",MB_OK);
	}
}
Пример #2
0
void CtrlDisAsmView::assembleOpcode(u32 address, std::string defaultText)
{
	u32 encoded;

	auto memLock = Memory::Lock();
	if (Core_IsStepping() == false) {
		MessageBox(wnd,L"Cannot change code while the core is running!",L"Error",MB_OK);
		return;
	}
	std::string op;
	bool result = InputBox_GetString(MainWindow::GetHInstance(),wnd,L"Assemble opcode",defaultText, op, false);
	if (!result)
		return;

	// check if it changes registers first
	auto seperator = op.find('=');
	if (seperator != std::string::npos)
	{
		std::string registerName = trimString(op.substr(0,seperator));
		std::string expression = trimString(op.substr(seperator+1));

		u32 value;
		if (parseExpression(expression.c_str(),debugger,value) == true)
		{
			for (int cat = 0; cat < debugger->GetNumCategories(); cat++)
			{
				for (int reg = 0; reg < debugger->GetNumRegsInCategory(cat); reg++)
				{
					if (strcasecmp(debugger->GetRegName(cat,reg),registerName.c_str()) == 0)
					{
						debugger->SetRegValue(cat,reg,value);
						SendMessage(GetParent(wnd),WM_DEB_UPDATE,0,0);
						return;
					}
				}
			}
		}

		// try to assemble the input if it failed
	}

	result = MIPSAsm::MipsAssembleOpcode(op.c_str(),debugger,address,encoded);
	if (result == true)
	{
		Memory::Write_U32(encoded, address);
		// In case this is a delay slot or combined instruction, clear cache above it too.
		if (MIPSComp::jit)
			MIPSComp::jit->InvalidateCacheAt(address - 4, 8);
		scanFunctions();

		if (address == curAddress)
			gotoAddr(manager.getNthNextAddress(curAddress,1));

		redraw();
	} else {
		std::wstring error = ConvertUTF8ToWString(MIPSAsm::GetAssembleError());
		MessageBox(wnd,error.c_str(),L"Error",MB_OK);
	}
}
Пример #3
0
bool System_InputBoxGetString(const char *title, const char *defaultValue, char *outValue, size_t outLength)
{
	std::string out;
	if (InputBox_GetString(MainWindow::GetHInstance(), MainWindow::GetHWND(), ConvertUTF8ToWString(title).c_str(), defaultValue, out)) {
		strcpy(outValue, out.c_str());
		return true;
	} else {
		return false;
	}
}
Пример #4
0
void CtrlRegisterList::editRegisterValue()
{
	int cat = category;
	int reg = selection;
	if (selection >= cpu->GetNumRegsInCategory(cat))
		return;
	u32 val = cpu->GetRegValue(cat,reg);

	
	char temp[256];
	sprintf(temp,"%08X",val);
	if (InputBox_GetString(GetModuleHandle(NULL),wnd,"Set new value",temp,temp))
	{
		if (parseExpression(temp,cpu,val) == false)
		{
			displayExpressionError(wnd);
		} else {
			cpu->SetRegValue(cat,reg,val);
			redraw();
		}
	}
}
Пример #5
0
void CtrlRegisterList::editRegisterValue()
{
	if (!Core_IsStepping())
	{
		MessageBox(wnd,L"Can't change registers while the core is running.",L"Error",MB_OK);
		return;
	}

	char temp[24];
	u32 val = getSelectedRegValue(temp, 24);
	int reg = selection;

	std::string value = temp;
	if (InputBox_GetString(GetModuleHandle(NULL),wnd,L"Set new value",value,value)) {
		if (parseExpression(value.c_str(),cpu,val) == false) {
			displayExpressionError(wnd);
		} else {
			switch (reg)
			{
			case REGISTER_PC:
				cpu->SetPC(val);
				break;
			case REGISTER_HI:
				cpu->SetHi(val);
				break;
			case REGISTER_LO:
				cpu->SetLo(val);
				break;
			default:
				cpu->SetRegValue(category, reg, val);
				break;
			}
			redraw();
			SendMessage(GetParent(wnd),WM_DEB_UPDATE,0,0);	// registers changed -> disassembly needs to be updated
		}
	}
}
Пример #6
0
void CtrlDisAsmView::onMouseUp(WPARAM wParam, LPARAM lParam, int button)
{
	if (button == 1)
	{
		int x = LOWORD(lParam);
		int y = HIWORD(lParam);
		setCurAddress(yToAddress(y), KeyDownAsync(VK_SHIFT));
		redraw();
	}
	else if (button == 2)
	{
		//popup menu?
		POINT pt;
		GetCursorPos(&pt);
		switch(TrackPopupMenuEx(GetSubMenu(g_hPopupMenus,1),TPM_RIGHTBUTTON|TPM_RETURNCMD,pt.x,pt.y,wnd,0))
		{
		case ID_DISASM_GOTOINMEMORYVIEW:
			SendMessage(GetParent(wnd),WM_DEB_GOTOHEXEDIT,curAddress,0);
			break;
		case ID_DISASM_ADDHLE:
			break;
		case ID_DISASM_TOGGLEBREAKPOINT:
			toggleBreakpoint();
			redraw();
			break;
		case ID_DISASM_ASSEMBLE:
			assembleOpcode(curAddress,"");
			break;
		case ID_DISASM_COPYINSTRUCTIONDISASM:
			copyInstructions(selectRangeStart, selectRangeEnd, true);
			break;
		case ID_DISASM_COPYADDRESS:
			{
				char temp[16];
				sprintf(temp,"%08X",curAddress);
				W32Util::CopyTextToClipboard(wnd, temp);
			}
			break;
		case ID_DISASM_SETPCTOHERE:
			debugger->setPC(curAddress);
			redraw();
			break;
		case ID_DISASM_FOLLOWBRANCH:
			followBranch();
			break;
		case ID_DISASM_COPYINSTRUCTIONHEX:
			copyInstructions(selectRangeStart, selectRangeEnd, false);
			break;
		case ID_DISASM_RUNTOHERE:
			{
				SendMessage(GetParent(wnd), WM_COMMAND, ID_DEBUG_RUNTOLINE, 0);
				redraw();
			}
			break;
		case ID_DISASM_RENAMEFUNCTION:
			{
				u32 funcBegin = symbolMap.GetFunctionStart(curAddress);
				if (funcBegin != -1)
				{
					char name[256];
					std::string newname;
					strncpy_s(name, symbolMap.GetLabelString(funcBegin).c_str(),_TRUNCATE);
					if (InputBox_GetString(MainWindow::GetHInstance(), MainWindow::GetHWND(), L"New function name", name, newname)) {
						symbolMap.SetLabelName(newname.c_str(),funcBegin);
						u32 funcSize = symbolMap.GetFunctionSize(curAddress);
						MIPSAnalyst::RegisterFunction(funcBegin, funcSize, newname.c_str());
						MIPSAnalyst::UpdateHashMap();
						MIPSAnalyst::ApplyHashMap();
						SendMessage(GetParent(wnd),WM_DEB_MAPLOADED,0,0);
						redraw();
					}
				}
				else
				{
					MessageBox(MainWindow::GetHWND(), L"No symbol selected",0,0);
				}
			}
			break;
		case ID_DISASM_REMOVEFUNCTION:
			{
				char statusBarTextBuff[256];
				u32 funcBegin = symbolMap.GetFunctionStart(curAddress);
				if (funcBegin != -1)
				{
					u32 prevBegin = symbolMap.GetFunctionStart(funcBegin-1);
					if (prevBegin != -1)
					{
						u32 expandedSize = symbolMap.GetFunctionSize(prevBegin)+symbolMap.GetFunctionSize(funcBegin);
						symbolMap.SetFunctionSize(prevBegin,expandedSize);
					}
					
					symbolMap.RemoveFunction(funcBegin,true);
					symbolMap.SortSymbols();
					manager.clear();

					SendMessage(GetParent(wnd), WM_DEB_MAPLOADED, 0, 0);
				}
				else
				{
					snprintf(statusBarTextBuff,256, "WARNING: unable to find function symbol here");
					SendMessage(GetParent(wnd), WM_DEB_SETSTATUSBARTEXT, 0, (LPARAM) statusBarTextBuff);
				}
				redraw();
			}
			break;
		case ID_DISASM_ADDFUNCTION:
			{
				char statusBarTextBuff[256];
				u32 prevBegin = symbolMap.GetFunctionStart(curAddress);
				if (prevBegin != -1)
				{
					if (prevBegin == curAddress)
					{
						snprintf(statusBarTextBuff,256, "WARNING: There's already a function entry point at this adress");
						SendMessage(GetParent(wnd), WM_DEB_SETSTATUSBARTEXT, 0, (LPARAM) statusBarTextBuff);
					}
					else
					{
						char symname[128];
						u32 prevSize = symbolMap.GetFunctionSize(prevBegin);
						u32 newSize = curAddress-prevBegin;
						symbolMap.SetFunctionSize(prevBegin,newSize);

						newSize = prevSize-newSize;
						snprintf(symname,128,"u_un_%08X",curAddress);
						symbolMap.AddFunction(symname,curAddress,newSize);
						symbolMap.SortSymbols();
						manager.clear();

						SendMessage(GetParent(wnd), WM_DEB_MAPLOADED, 0, 0);
					}
				}
				else
				{
					char symname[128];
					int newSize = selectRangeEnd - selectRangeStart;
					snprintf(symname, 128, "u_un_%08X", selectRangeStart);
					symbolMap.AddFunction(symname, selectRangeStart, newSize);
					symbolMap.SortSymbols();

					SendMessage(GetParent(wnd), WM_DEB_MAPLOADED, 0, 0);
				}
				redraw();
			}
			break;
		case ID_DISASM_DISASSEMBLETOFILE:
			disassembleToFile();
			break;
		}
		return;
	}

	redraw();
}
Пример #7
0
void CtrlDisAsmView::search(bool continueSearch)
{
	u32 searchAddress;

	if (continueSearch == false || searchQuery[0] == 0)
	{
		if (InputBox_GetString(MainWindow::GetHInstance(),MainWindow::GetHWND(),L"Search for:","",searchQuery) == false
			|| searchQuery[0] == 0)
		{
			SetFocus(wnd);
			return;
		}

		for (size_t i = 0; i < searchQuery.size(); i++)
		{
			searchQuery[i] = tolower(searchQuery[i]);
		}
		SetFocus(wnd);
		searchAddress = manager.getNthNextAddress(curAddress,1);
	} else {
		searchAddress = manager.getNthNextAddress(matchAddress,1);
	}

	// limit address to sensible ranges
	if (searchAddress < 0x04000000) searchAddress = 0x04000000;
	if (searchAddress >= 0x04200000 && searchAddress < 0x08000000) searchAddress = 0x08000000;
	if (searchAddress >= 0x0A000000) {	
		MessageBox(wnd,L"Not found",L"Search",MB_OK);
		return;
	}

	searching = true;
	redraw();	// so the cursor is disabled

	DisassemblyLineInfo lineInfo;
	while (searchAddress < 0x0A000000)
	{
		manager.getLine(searchAddress,displaySymbols,lineInfo);

		char addressText[64];
		getDisasmAddressText(searchAddress,addressText,true,lineInfo.type == DISTYPE_OPCODE);

		const char* opcode = lineInfo.name.c_str();
		const char* arguments = lineInfo.params.c_str();

		char merged[512];
		int mergePos = 0;

		// I'm doing it manually to convert everything to lowercase at the same time
		for (int i = 0; addressText[i] != 0; i++) merged[mergePos++] = tolower(addressText[i]);
		merged[mergePos++] = ' ';
		for (int i = 0; opcode[i] != 0; i++) merged[mergePos++] = tolower(opcode[i]);
		merged[mergePos++] = ' ';
		for (int i = 0; arguments[i] != 0; i++) merged[mergePos++] = tolower(arguments[i]);
		merged[mergePos] = 0;

		// match!
		if (strstr(merged, searchQuery.c_str()) != NULL)
		{
			matchAddress = searchAddress;
			searching = false;
			gotoAddr(searchAddress);
			return;
		}

		// cancel search
		if ((searchAddress % 256) == 0 && KeyDownAsync(VK_ESCAPE))
		{
			searching = false;
			return;
		}

		searchAddress = manager.getNthNextAddress(searchAddress,1);
		if (searchAddress >= 0x04200000 && searchAddress < 0x08000000) searchAddress = 0x08000000;
	}
	
	MessageBox(wnd,L"Not found",L"Search",MB_OK);
	searching = false;
}
Пример #8
0
void CtrlMemView::search(bool continueSearch)
{
	u32 searchAddress;
	if (continueSearch == false || searchQuery[0] == 0)
	{
		if (InputBox_GetString(GetModuleHandle(NULL),wnd,L"Search for", "",searchQuery) == false)
		{
			SetFocus(wnd);
			return;
		}
		SetFocus(wnd);
		searchAddress = curAddress+1;
	} else {
		searchAddress = matchAddress+1;
	}

	std::vector<u8> searchData;
	if (asciiSelected)
	{
		for (size_t i = 0; i < searchQuery.length(); i++)
		{
			char c = searchQuery[i];
			searchData.push_back(c);
		}
	} else {
		size_t index = 0;
		while (index < searchQuery.size())
		{
			if (searchQuery[index] == ' ' || searchQuery[index] == '\t')
			{
				index++;
				continue;
			}

			u8 value = 0;
			for (int i = 0; i < 2; i++)
			{
				char c = tolower(searchQuery[index++]);
				if (c >= 'a' && c <= 'f')
				{
					value |= (c-'a'+10) << (1-i)*4;
				} else  if (c >= '0' && c <= '9')
				{
					value |= (c-'0') << (1-i)*4;
				} else {
					MessageBox(wnd,L"Invalid search text.",L"Error",MB_OK);
					return;
				}
			}

			searchData.push_back(value);
		}
	}

	std::vector<std::pair<u32,u32>> memoryAreas;
	memoryAreas.push_back(std::pair<u32,u32>(0x04000000,0x04200000));
	memoryAreas.push_back(std::pair<u32,u32>(0x08000000,0x0A000000));
	
	searching = true;
	redraw();	// so the cursor is disabled
	for (size_t i = 0; i < memoryAreas.size(); i++)
	{
		u32 segmentStart = memoryAreas[i].first;
		u32 segmentEnd = memoryAreas[i].second;
		u8* dataPointer = Memory::GetPointer(segmentStart);
		if (dataPointer == NULL) continue;		// better safe than sorry, I guess

		if (searchAddress < segmentStart) searchAddress = segmentStart;
		if (searchAddress >= segmentEnd) continue;

		int index = searchAddress-segmentStart;
		int endIndex = segmentEnd-segmentStart-(int)searchData.size();

		while (index < endIndex)
		{
			// cancel search
			if ((index % 256) == 0 && KeyDownAsync(VK_ESCAPE))
			{
				searching = false;
				return;
			}
		
			if (memcmp(&dataPointer[index],searchData.data(),searchData.size()) == 0)
			{
				matchAddress = index+segmentStart;
				searching = false;
				gotoAddr(matchAddress);
				return;
			}
			index++;
		}
	}

	MessageBox(wnd,L"Not found",L"Search",MB_OK);
	searching = false;
	redraw();
}
Пример #9
0
void CtrlDisAsmView::onMouseUp(WPARAM wParam, LPARAM lParam, int button)
{
	if (button == 1)
	{
		int x = LOWORD(lParam);
		int y = HIWORD(lParam);
		setCurAddress(yToAddress(y), GetAsyncKeyState(VK_SHIFT) != 0);
		redraw();
	}
	else if (button == 2)
	{
		//popup menu?
		POINT pt;
		GetCursorPos(&pt);
		switch(TrackPopupMenuEx(GetSubMenu(g_hPopupMenus,1),TPM_RIGHTBUTTON|TPM_RETURNCMD,pt.x,pt.y,wnd,0))
		{
		case ID_DISASM_GOTOINMEMORYVIEW:
			for (int i=0; i<numCPUs; i++)
				if (memoryWindow[i])
					memoryWindow[i]->Goto(curAddress);
			break;
		case ID_DISASM_ADDHLE:
			break;
		case ID_DISASM_TOGGLEBREAKPOINT:
			toggleBreakpoint();
			redraw();
			break;
		case ID_DISASM_ASSEMBLE:
			assembleOpcode(curAddress,"");
			break;
		case ID_DISASM_COPYINSTRUCTIONDISASM:
			{
				int space = 256 * (selectRangeEnd - selectRangeStart) / instructionSize;
				char opcode[64], arguments[256];
				char *temp = new char[space];

				char *p = temp, *end = temp + space;
				for (u32 pos = selectRangeStart; pos < selectRangeEnd; pos += instructionSize)
				{
					const char *dizz = debugger->disasm(pos, instructionSize);
					parseDisasm(dizz, opcode, arguments);
					p += snprintf(p, end - p, "%s\t%s\r\n", opcode, arguments);
				}

				W32Util::CopyTextToClipboard(wnd, temp);
				delete [] temp;
			}
			break;
		case ID_DISASM_COPYADDRESS:
			{
				char temp[16];
				sprintf(temp,"%08X",curAddress);
				W32Util::CopyTextToClipboard(wnd, temp);
			}
			break;
		case ID_DISASM_SETPCTOHERE:
			debugger->setPC(curAddress);
			redraw();
			break;
		case ID_DISASM_FOLLOWBRANCH:
			followBranch();
			break;
		case ID_DISASM_COPYINSTRUCTIONHEX:
			{
				int space = 24 * (selectRangeEnd - selectRangeStart) / instructionSize;
				char *temp = new char[space];

				char *p = temp, *end = temp + space;
				for (u32 pos = selectRangeStart; pos < selectRangeEnd; pos += instructionSize)
					p += snprintf(p, end - p, "%08X\r\n", debugger->readMemory(pos));

				W32Util::CopyTextToClipboard(wnd, temp);
				delete [] temp;
			}
			break;
		case ID_DISASM_RUNTOHERE:
			{
				debugger->setBreakpoint(curAddress);
				debugger->runToBreakpoint();
				redraw();
			}
			break;
		case ID_DISASM_RENAMEFUNCTION:
			{
				int sym = symbolMap.GetSymbolNum(curAddress);
				if (sym != -1)
				{
					char name[256];
					std::string newname;
					strncpy_s(name, symbolMap.GetSymbolName(sym),_TRUNCATE);
					if (InputBox_GetString(MainWindow::GetHInstance(), MainWindow::GetHWND(), L"New function name", name, newname))
					{
						symbolMap.SetSymbolName(sym, newname.c_str());
						redraw();
						SendMessage(GetParent(wnd),WM_DEB_MAPLOADED,0,0);
					}
				}
				else
				{
					MessageBox(MainWindow::GetHWND(), L"No symbol selected",0,0);
				}
			}
			break;
		case ID_DISASM_DISASSEMBLETOFILE:
			disassembleToFile();
			break;
		}
		return;
	}

	redraw();
}
Пример #10
0
void CtrlDisAsmView::search(bool continueSearch)
{
	u32 searchAddress;

	if (continueSearch == false || searchQuery[0] == 0)
	{
		if (InputBox_GetString(MainWindow::GetHInstance(),MainWindow::GetHWND(),L"Search for:","",searchQuery) == false
			|| searchQuery[0] == 0)
		{
			SetFocus(wnd);
			return;
		}

		for (int i = 0; searchQuery[i] != 0; i++)
		{
			searchQuery[i] = tolower(searchQuery[i]);
		}
		SetFocus(wnd);
		searchAddress = curAddress+instructionSize;
	} else {
		searchAddress = matchAddress+instructionSize;
	}

	// limit address to sensible ranges
	if (searchAddress < 0x04000000) searchAddress = 0x04000000;
	if (searchAddress >= 0x04200000 && searchAddress < 0x08000000) searchAddress = 0x08000000;
	if (searchAddress >= 0x0A000000) {	
		MessageBox(wnd,L"Not found",L"Search",MB_OK);
		return;
	}

	searching = true;
	redraw();	// so the cursor is disabled
	while (searchAddress < 0x0A000000)
	{
		char addressText[64],opcode[64],arguments[256];
		const char *dis = debugger->disasm(searchAddress, instructionSize);
		parseDisasm(dis,opcode,arguments);
		getDisasmAddressText(searchAddress,addressText,true);

		char merged[512];
		int mergePos = 0;

		// I'm doing it manually to convert everything to lowercase at the same time
		for (int i = 0; addressText[i] != 0; i++) merged[mergePos++] = tolower(addressText[i]);
		merged[mergePos++] = ' ';
		for (int i = 0; opcode[i] != 0; i++) merged[mergePos++] = tolower(opcode[i]);
		merged[mergePos++] = ' ';
		for (int i = 0; arguments[i] != 0; i++) merged[mergePos++] = tolower(arguments[i]);
		merged[mergePos] = 0;

		// match!
		if (strstr(merged, searchQuery.c_str()) != NULL)
		{
			matchAddress = searchAddress;
			searching = false;
			gotoAddr(searchAddress);
			return;
		}

		// cancel search
		if ((searchAddress % 256) == 0 && GetAsyncKeyState(VK_ESCAPE))
		{
			searching = false;
			return;
		}

		searchAddress += instructionSize;
		if (searchAddress >= 0x04200000 && searchAddress < 0x08000000) searchAddress = 0x08000000;
	}
	
	MessageBox(wnd,L"Not found",L"Search",MB_OK);
	searching = false;
}
Пример #11
0
void CtrlRegisterList::editRegisterValue()
{
	if (!Core_IsStepping())
	{
		MessageBox(wnd,"Can't change registers while the core is running.","Error",MB_OK);
		return;
	}

	int cat = category;
	int reg = selection;
	u32 val;
	
	if (selection >= cpu->GetNumRegsInCategory(cat))
	{
		if (cat != 0 || selection >= REGISTERS_END)
			return;

		switch (selection)
		{
		case REGISTER_PC:
			val = cpu->GetPC();
			break;
		case REGISTER_HI:
			val = cpu->GetHi();
			break;
		case REGISTER_LO:
			val = cpu->GetLo();
			break;
		}
	} else {
		val = cpu->GetRegValue(cat,reg);	
	}

	char temp[256];
	sprintf(temp,"%08X",val);
	if (InputBox_GetString(GetModuleHandle(NULL),wnd,"Set new value",temp,temp))
	{
		if (parseExpression(temp,cpu,val) == false)
		{
			displayExpressionError(wnd);
		} else {
			switch (reg)
			{
			case REGISTER_PC:
				cpu->SetPC(val);
				break;
			case REGISTER_HI:
				cpu->SetHi(val);
				break;
			case REGISTER_LO:
				cpu->SetLo(val);
				break;
			default:
				cpu->SetRegValue(cat,reg,val);
				break;
			}
			redraw();
			SendMessage(GetParent(wnd),WM_DEB_UPDATE,0,0);	// registers changed -> disassembly needs to be updated
		}
	}
}