void CtrlDisAsmView::getOpcodeText(u32 address, char* dest) { char opcode[64]; char arguments[256]; const char *dis = debugger->disasm(address, instructionSize); parseDisasm(dis,opcode,arguments); sprintf(dest,"%s %s",opcode,arguments); }
bool DisassemblyOpcode::disassemble(u32 address, DisassemblyLineInfo& dest, bool insertSymbols) { char opcode[64],arguments[256]; const char *dizz = DisassemblyManager::getCpu()->disasm(address,4); parseDisasm(dizz,opcode,arguments,insertSymbols); dest.type = DISTYPE_OPCODE; dest.name = opcode; dest.params = arguments; dest.totalSize = 4; dest.info = MIPSAnalyst::GetOpcodeInfo(DisassemblyManager::getCpu(),address); return true; }
bool DisassemblyOpcode::disassemble(u32 address, DisassemblyLineInfo& dest, bool insertSymbols) { char opcode[64],arguments[256]; std::string dis = cpu->disasm(address,insertSymbols); parseDisasm(dis.c_str(),opcode,arguments,insertSymbols); dest.type = DISTYPE_OPCODE; dest.name = opcode; dest.params = arguments; dest.totalSize = 4; dest.info = MIPSAnalyst::GetOpcodeInfo(cpu,address); return true; }
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(); }
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; }