std::string CtrlDisAsmView::disassembleRange(u32 start, u32 size) { std::string result; // gather all branch targets without labels std::set<u32> branchAddresses; for (u32 i = 0; i < size; i += debugger->getInstructionSize(0)) { MIPSAnalyst::MipsOpcodeInfo info = MIPSAnalyst::GetOpcodeInfo(debugger,start+i); if (info.isBranch && symbolMap.GetLabelString(info.branchTarget).empty()) { if (branchAddresses.find(info.branchTarget) == branchAddresses.end()) { branchAddresses.insert(info.branchTarget); } } } u32 disAddress = start; bool previousLabel = true; DisassemblyLineInfo line; while (disAddress < start+size) { char addressText[64],buffer[512]; manager.getLine(disAddress,displaySymbols,line); bool isLabel = getDisasmAddressText(disAddress,addressText,false,line.type == DISTYPE_OPCODE); if (isLabel) { if (!previousLabel) result += "\r\n"; sprintf(buffer,"%s\r\n\r\n",addressText); result += buffer; } else if (branchAddresses.find(disAddress) != branchAddresses.end()) { if (!previousLabel) result += "\r\n"; sprintf(buffer,"pos_%08X:\r\n\r\n",disAddress); result += buffer; } if (line.info.isBranch && !line.info.isBranchToRegister && symbolMap.GetLabelString(line.info.branchTarget).empty() && branchAddresses.find(line.info.branchTarget) != branchAddresses.end()) { sprintf(buffer,"pos_%08X",line.info.branchTarget); line.params = line.params.substr(0,line.params.find("0x")) + buffer; } sprintf(buffer,"\t%s\t%s\r\n",line.name.c_str(),line.params.c_str()); result += buffer; previousLabel = isLabel; disAddress += line.totalSize; } return result; }
void CtrlDisAsmView::onPaint(WPARAM wParam, LPARAM lParam) { if (!debugger->isAlive()) return; PAINTSTRUCT ps; HDC actualHdc = BeginPaint(wnd, &ps); HDC hdc = CreateCompatibleDC(actualHdc); HBITMAP hBM = CreateCompatibleBitmap(actualHdc, rect.right-rect.left, rect.bottom-rect.top); SelectObject(hdc, hBM); SetBkMode(hdc, TRANSPARENT); HPEN nullPen=CreatePen(0,0,0xffffff); HBRUSH nullBrush=CreateSolidBrush(0xffffff); HBRUSH currentBrush=CreateSolidBrush(0xFFEfE8); HPEN oldPen=(HPEN)SelectObject(hdc,nullPen); HBRUSH oldBrush=(HBRUSH)SelectObject(hdc,nullBrush); HFONT oldFont = (HFONT)SelectObject(hdc,(HGDIOBJ)font); HICON breakPoint = (HICON)LoadIcon(GetModuleHandle(0),(LPCWSTR)IDI_STOP); HICON breakPointDisable = (HICON)LoadIcon(GetModuleHandle(0),(LPCWSTR)IDI_STOPDISABLE); unsigned int address = windowStart; std::map<u32,int> addressPositions; DisassemblyLineInfo line; for (int i = 0; i < visibleRows; i++) { manager.getLine(address,displaySymbols,line); int rowY1 = rowHeight*i; int rowY2 = rowHeight*(i+1); addressPositions[address] = rowY1; // draw background COLORREF backgroundColor = whiteBackground ? 0xFFFFFF : debugger->getColor(address); COLORREF textColor = 0x000000; if (isInInterval(address,line.totalSize,debugger->getPC())) { backgroundColor = scaleColor(backgroundColor,1.05f); } if (address >= selectRangeStart && address < selectRangeEnd && searching == false) { if (hasFocus) { backgroundColor = address == curAddress ? 0xFF8822 : 0xFF9933; textColor = 0xFFFFFF; } else { backgroundColor = 0xC0C0C0; } } HBRUSH backgroundBrush = CreateSolidBrush(backgroundColor); HPEN backgroundPen = CreatePen(0,0,backgroundColor); SelectObject(hdc,backgroundBrush); SelectObject(hdc,backgroundPen); Rectangle(hdc,0,rowY1,rect.right,rowY1+rowHeight); SelectObject(hdc,currentBrush); SelectObject(hdc,nullPen); DeleteObject(backgroundBrush); DeleteObject(backgroundPen); // display address/symbol bool enabled; if (CBreakPoints::IsAddressBreakPoint(address,&enabled)) { if (enabled) textColor = 0x0000FF; int yOffset = max(-1,(rowHeight-14+1)/2); if (!enabled) yOffset++; DrawIconEx(hdc,2,rowY1+1+yOffset,enabled ? breakPoint : breakPointDisable,32,32,0,0,DI_NORMAL); } SetTextColor(hdc,textColor); char addressText[64]; getDisasmAddressText(address,addressText,true,line.type == DISTYPE_OPCODE); TextOutA(hdc,pixelPositions.addressStart,rowY1+2,addressText,(int)strlen(addressText)); if (isInInterval(address,line.totalSize,debugger->getPC())) { TextOut(hdc,pixelPositions.opcodeStart-8,rowY1,L"■",1); } // display whether the condition of a branch is met if (line.info.isConditional && address == debugger->getPC()) { line.params += line.info.conditionMet ? " ; true" : " ; false"; } if (line.params.size() != 0) TextOutA(hdc,pixelPositions.argumentsStart,rowY1+2,line.params.c_str(),(int)line.params.size()); SelectObject(hdc,boldfont); TextOutA(hdc,pixelPositions.opcodeStart,rowY1+2,line.name.c_str(),(int)line.name.size()); SelectObject(hdc,font); address += line.totalSize; } std::vector<BranchLine> branchLines = manager.getBranchLines(windowStart,address-windowStart); for (size_t i = 0; i < branchLines.size(); i++) { drawBranchLine(hdc,addressPositions,branchLines[i]); } SelectObject(hdc,oldFont); SelectObject(hdc,oldPen); SelectObject(hdc,oldBrush); // copy bitmap to the actual hdc BitBlt(actualHdc, 0, 0, rect.right, rect.bottom, hdc, 0, 0, SRCCOPY); DeleteObject(hBM); DeleteDC(hdc); DeleteObject(nullPen); DeleteObject(nullBrush); DeleteObject(currentBrush); DestroyIcon(breakPoint); DestroyIcon(breakPointDisable); EndPaint(wnd, &ps); }
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; }
void CtrlDisAsmView::onPaint(WPARAM wParam, LPARAM lParam) { if (!debugger->isAlive()) return; PAINTSTRUCT ps; HDC actualHdc = BeginPaint(wnd, &ps); HDC hdc = CreateCompatibleDC(actualHdc); HBITMAP hBM = CreateCompatibleBitmap(actualHdc, rect.right-rect.left, rect.bottom-rect.top); SelectObject(hdc, hBM); SetBkMode(hdc, TRANSPARENT); HPEN nullPen=CreatePen(0,0,0xffffff); HPEN condPen=CreatePen(0,0,0xFF3020); HBRUSH nullBrush=CreateSolidBrush(0xffffff); HBRUSH currentBrush=CreateSolidBrush(0xFFEfE8); HPEN oldPen=(HPEN)SelectObject(hdc,nullPen); HBRUSH oldBrush=(HBRUSH)SelectObject(hdc,nullBrush); HFONT oldFont = (HFONT)SelectObject(hdc,(HGDIOBJ)font); HICON breakPoint = (HICON)LoadIcon(GetModuleHandle(0),(LPCWSTR)IDI_STOP); HICON breakPointDisable = (HICON)LoadIcon(GetModuleHandle(0),(LPCWSTR)IDI_STOPDISABLE); for (int i = 0; i < visibleRows+2; i++) { unsigned int address=windowStart + i*instructionSize; MIPSAnalyst::MipsOpcodeInfo info = MIPSAnalyst::GetOpcodeInfo(debugger,address); int rowY1 = rowHeight*i; int rowY2 = rowHeight*(i+1); // draw background COLORREF backgroundColor = whiteBackground ? 0xFFFFFF : debugger->getColor(address); COLORREF textColor = 0x000000; if (address == debugger->getPC()) { backgroundColor = scaleColor(backgroundColor,1.05f); } if (address >= selectRangeStart && address < selectRangeEnd && searching == false) { if (hasFocus) { backgroundColor = address == curAddress ? 0xFF8822 : 0xFF9933; textColor = 0xFFFFFF; } else { backgroundColor = 0xC0C0C0; } } HBRUSH backgroundBrush = CreateSolidBrush(backgroundColor); HPEN backgroundPen = CreatePen(0,0,backgroundColor); SelectObject(hdc,backgroundBrush); SelectObject(hdc,backgroundPen); Rectangle(hdc,0,rowY1,rect.right,rowY1+rowHeight); SelectObject(hdc,currentBrush); SelectObject(hdc,nullPen); DeleteObject(backgroundBrush); DeleteObject(backgroundPen); // display address/symbol bool enabled; if (CBreakPoints::IsAddressBreakPoint(address,&enabled)) { if (enabled) textColor = 0x0000FF; int yOffset = max(-1,(rowHeight-14+1)/2); DrawIconEx(hdc,2,rowY1+1+yOffset,enabled ? breakPoint : breakPointDisable,32,32,0,0,DI_NORMAL); } SetTextColor(hdc,textColor); char addressText[64]; getDisasmAddressText(address,addressText,true); TextOutA(hdc,pixelPositions.addressStart,rowY1+2,addressText,(int)strlen(addressText)); if (address == debugger->getPC()) { TextOut(hdc,pixelPositions.opcodeStart-8,rowY1,L"■",1); } // display opcode char opcode[64],arguments[256]; const char *dizz = debugger->disasm(address, instructionSize); parseDisasm(dizz,opcode,arguments); // display whether the condition of a branch is met if (info.isConditional && address == debugger->getPC()) { strcat(arguments,info.conditionMet ? " ; true" : " ; false"); } int length = (int) strlen(arguments); if (length != 0) TextOutA(hdc,pixelPositions.argumentsStart,rowY1+2,arguments,length); SelectObject(hdc,boldfont); TextOutA(hdc,pixelPositions.opcodeStart,rowY1+2,opcode,(int)strlen(opcode)); SelectObject(hdc,font); } SelectObject(hdc,condPen); for (size_t i = 0; i < visibleFunctionAddresses.size(); i++) { auto it = functions.find(visibleFunctionAddresses[i]); if (it == functions.end()) continue; DisassemblyFunction& func = it->second; for (size_t l = 0; l < func.lines.size(); l++) { drawBranchLine(hdc,func.lines[l]); } } for (size_t i = 0; i < strayLines.size(); i++) { drawBranchLine(hdc,strayLines[i]); } SelectObject(hdc,oldFont); SelectObject(hdc,oldPen); SelectObject(hdc,oldBrush); // copy bitmap to the actual hdc BitBlt(actualHdc, 0, 0, rect.right, rect.bottom, hdc, 0, 0, SRCCOPY); DeleteObject(hBM); DeleteDC(hdc); DeleteObject(nullPen); DeleteObject(condPen); DeleteObject(nullBrush); DeleteObject(currentBrush); DestroyIcon(breakPoint); DestroyIcon(breakPointDisable); EndPaint(wnd, &ps); }
void CtrlDisAsmView::disassembleToFile() { wchar_t fileName[MAX_PATH]; u32 size; // get size if (executeExpressionWindow(wnd,debugger,size) == false) return; if (size == 0 || size > 10*1024*1024) { MessageBox(wnd,L"Invalid size!",L"Error",MB_OK); return; } // get file name OPENFILENAME ofn; ZeroMemory( &ofn , sizeof( ofn)); ofn.lStructSize = sizeof ( ofn ); ofn.hwndOwner = NULL ; ofn.lpstrFile = fileName ; ofn.lpstrFile[0] = '\0'; ofn.nMaxFile = sizeof( fileName ); ofn.lpstrFilter = L"All files"; ofn.nFilterIndex = 1; ofn.lpstrFileTitle = NULL ; ofn.nMaxFileTitle = 0 ; ofn.lpstrInitialDir = NULL ; ofn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST|OFN_OVERWRITEPROMPT; if (GetSaveFileName(&ofn) == false) return; FILE* output = _wfopen(fileName, L"w"); if (output == NULL) { MessageBox(wnd,L"Could not open file!",L"Error",MB_OK); return; } // gather all branch targets without labels std::set<u32> branchAddresses; for (u32 i = 0; i < size; i += instructionSize) { char opcode[64],arguments[256]; const char *dis = debugger->disasm(curAddress+i, instructionSize); parseDisasm(dis,opcode,arguments); if (branchTarget != -1 && debugger->findSymbolForAddress(branchTarget) == NULL) { if (branchAddresses.find(branchTarget) == branchAddresses.end()) { branchAddresses.insert(branchTarget); } } } bool previousLabel = true; for (u32 i = 0; i < size; i += instructionSize) { u32 disAddress = curAddress+i; char addressText[64],opcode[64],arguments[256]; const char *dis = debugger->disasm(disAddress, instructionSize); parseDisasm(dis,opcode,arguments); bool isLabel = getDisasmAddressText(disAddress,addressText,false); if (isLabel) { if (!previousLabel) fprintf(output,"\n"); fprintf(output,"%s\n\n",addressText); } else if (branchAddresses.find(disAddress) != branchAddresses.end()) { if (!previousLabel) fprintf(output,"\n"); fprintf(output,"pos_%08X:\n\n",disAddress); } if (branchTarget != -1 && debugger->findSymbolForAddress(branchTarget) == NULL) { char* str = strstr(arguments,"0x"); sprintf(str,"pos_%08X",branchTarget); } fprintf(output,"\t%s\t%s\n",opcode,arguments); previousLabel = isLabel; } fclose(output); MessageBox(wnd,L"Finished!",L"Done",MB_OK); }
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; }