-
-
ARM反汇编
-
发表于: 2010-8-29 21:27 9924
-
#include <stdio.h> #include <string.h> #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog (CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange (CDataExchange* pDX) { CDialog::DoDataExchange (pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP (CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CUnasmARMDlg dialog CUnasmARMDlg::CUnasmARMDlg (CWnd* pParent /*=NULL*/) : CDialog (CUnasmARMDlg::IDD, pParent) { //{{AFX_DATA_INIT(CUnasmARMDlg) m_filename1 = _T (""); m_filename2 = _T (""); m_filename3 = _T (""); m_Hex = TRUE; m_Radio1 = -1; //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon (IDR_MAINFRAME); } void CUnasmARMDlg::DoDataExchange (CDataExchange* pDX) { CDialog::DoDataExchange (pDX); //{{AFX_DATA_MAP(CUnasmARMDlg) DDX_Text (pDX, IDC_EDIT1, m_filename1); DDX_Text (pDX, IDC_EDIT2, m_filename2); DDX_Text (pDX, IDC_EDIT3, m_filename3); DDX_Check (pDX, IDC_CHECK1, m_Hex); DDX_Radio (pDX, IDC_RADIO1, m_Radio1); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP (CUnasmARMDlg, CDialog) //{{AFX_MSG_MAP(CUnasmARMDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED (IDC_BUTTON1, OnButton1) ON_BN_CLICKED (IDC_BUTTON2, OnButton2) ON_BN_CLICKED (IDC_BUTTON3, OnButton3) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CUnasmARMDlg message handlers BOOL CUnasmARMDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT ( (IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT (IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu (FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString (IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty() ) { pSysMenu->AppendMenu (MF_SEPARATOR); pSysMenu->AppendMenu (MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon (m_hIcon, TRUE); // Set big icon SetIcon (m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here // m_filename1 = _T("D:\\下载资料\\5110v530\\5110v530.fls"); // m_filename2 = _T("D:\\下载资料\\5110v530\\5110v530.ref"); // m_filename3 = _T("D:\\下载资料\\5110v530\\5110v530.asm"); m_Radio1 = 0; UpdateData (FALSE); strcpy (RegisterName[0], "R0"); strcpy (RegisterName[1], "R1"); strcpy (RegisterName[2], "R2"); strcpy (RegisterName[3], "R3"); strcpy (RegisterName[4], "R4"); strcpy (RegisterName[5], "R5"); strcpy (RegisterName[6], "R6"); strcpy (RegisterName[7], "R7"); strcpy (RegisterName[8], "R8"); strcpy (RegisterName[9], "R9"); strcpy (RegisterName[10], "R10"); strcpy (RegisterName[11], "R11"); strcpy (RegisterName[12], "R12"); strcpy (RegisterName[13], "SP"); strcpy (RegisterName[14], "LR"); strcpy (RegisterName[15], "PC"); regNo = -1; return TRUE; // return TRUE unless you set the focus to a control } void CUnasmARMDlg::OnSysCommand (UINT nID, LPARAM lParam) { if ( (nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand (nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CUnasmARMDlg::OnPaint() { if (IsIconic() ) { CPaintDC dc (this); // device context for painting SendMessage (WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics (SM_CXICON); int cyIcon = GetSystemMetrics (SM_CYICON); CRect rect; GetClientRect (&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon (x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CUnasmARMDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CUnasmARMDlg::OnOK() { // TODO: Add extra validation here // CDialog::OnOK(); UpdateData (TRUE); if (m_filename1.IsEmpty() ) { AfxMessageBox ("You must specify source filename"); return; } if (m_filename2.IsEmpty() ) { AfxMessageBox ("You must specify Reference filename"); return; } if (m_filename3.IsEmpty() ) { AfxMessageBox ("You must specify Target filename"); return; } FILE *fd_src, *fd_ref, *fd_tar; fd_src = fopen (m_filename1, "rb"); if (fd_src == NULL) { AfxMessageBox ("Source file not found."); return; } fd_ref = fopen (m_filename2, "r"); if (fd_ref == NULL) { fclose (fd_src); AfxMessageBox ("Reference file not found."); return; } fd_tar = fopen (m_filename3, "w"); if (fd_tar == NULL) { fclose (fd_src); fclose (fd_ref); AfxMessageBox ("Error creating target file."); return; } #define ARM_MODE 0x1 #define THUMB_MODE 0x2 char ref_buffer[1024]; int theMode = ARM_MODE; long addr = 0; long addr1, addr2; //Unasm int i; /* $ADDRESS=0x200000 $ARM $UN0x0,0x0fff $REM This is a subroutine $DB0x1000,0x10ff // Define Byte $DC0x1000,0x10ff // Define Code $DH0x1100,0x11ff // Define Halfword $DW0x1200,0x12ff // Define Word $DF0x1300,0x13FF // Define Float $DD0x1400,0x14FF // Define Double $THUMB $UN0x2000,0x20FF $END */ for (;;) { i = fscanf (fd_ref, "%s", ref_buffer); if (i < 0) break; if (_memicmp ( ref_buffer, "$REM", 4) == 0) { // Remark while (1) { i = fscanf (fd_ref, "%s", ref_buffer); if (i < 0) break; if (ref_buffer[0] == '$') { fwrite ("\n", 1, 1, fd_tar); if (_memicmp ( ref_buffer, "$REM", 4) == 0) { // Remark continue; } break; } fwrite (ref_buffer, 1, strlen (ref_buffer), fd_tar); fwrite (" ", 1, 1, fd_tar); } if (i < 0) break; } if (_memicmp ( ref_buffer, "$END", 4) == 0) { // $END break; } if (_memicmp ( ref_buffer, "$ARM", 4) == 0) { // $ARM regNo = -1; theMode = ARM_MODE; continue; } if (_memicmp ( ref_buffer, "$THUMB", 6) == 0) { // $THUMB regNo = -1; theMode = THUMB_MODE; continue; } if (_memicmp ( ref_buffer, "$ADDRESS=0x", 11) == 0) { // $ADDRESS addr = GetHex (&ref_buffer[11]); continue; } if (_memicmp ( ref_buffer, "$UN0X", 5) == 0) { // $UN addr1 = GetHex (&ref_buffer[5]); addr2 = addr1 + 0x7f; // 0x80 bytes i = 0; for (;;) { if ( (ref_buffer[i] == '\0') || (ref_buffer[i] == ',') ) break; i++; } if (ref_buffer[i] == ',') { i++; if (_memicmp ( &ref_buffer[i], "0x", 2) == 0) { addr2 = GetHex (&ref_buffer[i+2]); if (addr2 <= addr1) continue; } } // Now we can disassembly from addr1 to addr2 if (theMode == ARM_MODE) dis_arm (fd_src, fd_tar, addr, addr1, addr2); else dis_thumb (fd_src, fd_tar, addr, addr1, addr2); continue; } if ( (ref_buffer[0] == '$' ) && (toupper (ref_buffer[1]) == 'D') ) { // $DB/DH/DW/DC/DD/DF char ch; int d_mode = 0; ch = toupper (ref_buffer[2]); switch (ch) { case 'B': d_mode = 1; // $DB break; case 'C': d_mode = 3; // $DC break; case 'D': d_mode = 5; // $DD break; case 'F': d_mode = 6; // $DF break; case 'H': d_mode = 2; // $DH break; case 'W': d_mode = 4; // $DW break; } if (!d_mode) continue; if (_memicmp ( &ref_buffer[3], "0x", 2) == 0) { addr1 = GetHex (&ref_buffer[5]); addr2 = addr1 + 0x7f; // 0x80 bytes i = 0; for (;;) { if ( (ref_buffer[i] == '\0') || (ref_buffer[i] == ',') ) break; i++; } if (ref_buffer[i] == ',') { i++; if (_memicmp ( &ref_buffer[i], "0x", 2) == 0) { addr2 = GetHex (&ref_buffer[i+2]); if (addr2 <= addr1) continue; } } // Now we can dump data from addr1 to addr2 switch (d_mode) { case 1: dump_byte (fd_src, fd_tar, addr, addr1, addr2); break; case 2: dump_halfword (fd_src, fd_tar, addr, addr1, addr2); break; case 3: dump_byte_nochar (fd_src, fd_tar, addr, addr1, addr2); break; case 4: dump_word (fd_src, fd_tar, addr, addr1, addr2); break; case 5: dump_double (fd_src, fd_tar, addr, addr1, addr2); break; case 6: dump_float (fd_src, fd_tar, addr, addr1, addr2); break; } } continue; } } fclose (fd_src); fclose (fd_ref); fclose (fd_tar); AfxMessageBox ("Successful"); } long CUnasmARMDlg::GetHex (char * str) { int i; long v; char ch; for (i = 0, v = 0; str[i]; i++) { ch = toupper (str[i]); if ( (ch >= '0') && (ch <= '9') ) { v = v * 16 + ch - '0'; continue; } if ( (ch >= 'A') && (ch <= 'F') ) { v = v * 16 + ch - 'A' + 10; continue; } break; } return v; } int CUnasmARMDlg::dump_byte (FILE *fd_src, FILE *fd_tar, long addr, long addr1, long addr2) { int i, loc_str; long bytes; char src_buffer[16384]; char string[32]; string[0] = ' '; i = fseek (fd_src, addr1, SEEK_SET); bytes = addr2 - addr1 + 1; while (bytes) { int loc, times_16, remains_16; int bytes1 = (bytes <= 16384) ? bytes : 16384; char str[128]; int k, l; if (addr1 & 15) { if ( (16 - (addr1 & 15) ) < bytes1) bytes1 = 16 - (addr1 & 15); } bytes -= bytes1; i = fread ( src_buffer, 1, bytes1, fd_src); if (i > 0) { bytes1 = i; // Bytes actually times_16 = bytes1 >> 4; remains_16 = bytes1 & 0x0f; l = 0; while (times_16) { loc_str = 1; sprintf (str, "%08x ", addr + addr1); for (k = 0; k < 16; k++, l++) { loc = strlen (str); sprintf (&str[loc], "%02X ", 0xff & src_buffer[l]); string[loc_str++] = (src_buffer[l] >= ' ') ? src_buffer[l] : '.'; } string[loc_str] = '\0'; strcat (str, string); str[33] = '-'; loc = strlen (str); str[loc++] = '\n'; str[loc] = '\0'; fwrite (str, 1, loc, fd_tar); times_16--; addr1 += 16; } if (remains_16) { memset (str, ' ', 128); loc_str = 1; sprintf (str, "%08x ", addr + addr1); for (k = 0; k < remains_16; k++, l++) { loc = strlen (str); sprintf (&str[loc], "%02X ", 0xff & src_buffer[l]); string[loc_str++] = (src_buffer[l] >= ' ') ? src_buffer[l] : '.'; } string[loc_str] = '\0'; loc = strlen (str); str[loc] = ' '; str[58] = '\0'; strcat (str, string); if (remains_16 > 8) str[33] = '-'; loc = strlen (str); str[loc++] = '\n'; str[loc] = '\0'; fwrite (str, 1, loc, fd_tar); addr1 += remains_16; } } } fwrite ("\n", 1, 1, fd_tar); return 0; } int CUnasmARMDlg::dump_halfword (FILE * fd_src, FILE * fd_tar, long addr, long addr1, long addr2) { int i, loc_str; long bytes; char src_buffer[16384]; i = fseek (fd_src, addr1, SEEK_SET); bytes = addr2 - addr1 + 1; while (bytes) { int loc, times_16, remains_16; int bytes1 = (bytes <= 16384) ? bytes : 16384; char str[128]; int k, l; if (addr1 & 15) { if ( (16 - (addr1 & 15) ) < bytes1) bytes1 = 16 - (addr1 & 15); } bytes -= bytes1; i = fread ( src_buffer, 1, bytes1, fd_src); if (i > 0) { bytes1 = i; // Bytes actually times_16 = bytes1 >> 4; remains_16 = (bytes1 & 0x0f) >> 1; l = 0; while (times_16) { loc_str = 1; sprintf (str, "%08x ", addr + addr1); for (k = 0; k < 8; k++, l += 2) { loc = strlen (str); if (m_Radio1) { sprintf (&str[loc], "%02X%02X ", 0xff & src_buffer[l], 0xff & src_buffer[l+1]); } else { sprintf (&str[loc], "%02X%02X ", 0xff & src_buffer[l+1], 0xff & src_buffer[l]); } } loc = strlen (str); str[loc-1] = '\n'; fwrite (str, 1, loc, fd_tar); times_16--; addr1 += 16; } if (remains_16) { loc_str = 1; sprintf (str, "%08x ", addr + addr1); for (k = 0; k < remains_16; k++, l += 2) { loc = strlen (str); if (m_Radio1) { sprintf (&str[loc], "%02X%02X ", 0xff & src_buffer[l], 0xff & src_buffer[l+1]); } else { sprintf (&str[loc], "%02X%02X ", 0xff & src_buffer[l+1], 0xff & src_buffer[l]); } } loc = strlen (str); str[loc-1] = '\n'; fwrite (str, 1, loc, fd_tar); addr1 += (remains_16 << 1); } } } fwrite ("\n", 1, 1, fd_tar); return 0; } int CUnasmARMDlg::dump_word (FILE * fd_src, FILE * fd_tar, long addr, long addr1, long addr2) { int i, loc_str; long bytes; char src_buffer[16384]; i = fseek (fd_src, addr1, SEEK_SET); bytes = addr2 - addr1 + 1; while (bytes) { int loc, times_16, remains_16; int bytes1 = (bytes <= 16384) ? bytes : 16384; char str[128]; int k, l; if (addr1 & 15) { if ( (16 - (addr1 & 15) ) < bytes1) bytes1 = 16 - (addr1 & 15); } bytes -= bytes1; i = fread ( src_buffer, 1, bytes1, fd_src); if (i > 0) { bytes1 = i; // Bytes actually times_16 = bytes1 >> 4; remains_16 = (bytes1 & 0x0f) >> 2; l = 0; while (times_16) { loc_str = 1; sprintf (str, "%08x ", addr + addr1); for (k = 0; k < 4; k++, l += 4) { loc = strlen (str); if (m_Radio1) { sprintf (&str[loc], "%02X%02X%02X%02X ", 0xff & src_buffer[l], 0xff & src_buffer[l+1], 0xff & src_buffer[l+2], 0xff & src_buffer[l+3]); } else { sprintf (&str[loc], "%02X%02X%02X%02X ", 0xff & src_buffer[l+3], 0xff & src_buffer[l+2], 0xff & src_buffer[l+1], 0xff & src_buffer[l]); } } loc = strlen (str); str[loc-1] = '\n'; fwrite (str, 1, loc, fd_tar); times_16--; addr1 += 16; } if (remains_16) { loc_str = 1; sprintf (str, "%08x ", addr + addr1); for (k = 0; k < remains_16; k++, l += 4) { loc = strlen (str); if (m_Radio1) { sprintf (&str[loc], "%02X%02X%02X%02X ", 0xff & src_buffer[l], 0xff & src_buffer[l+1], 0xff & src_buffer[l+2], 0xff & src_buffer[l+3]); } else { sprintf (&str[loc], "%02X%02X%02X%02X ", 0xff & src_buffer[l+3], 0xff & src_buffer[l+2], 0xff & src_buffer[l+1], 0xff & src_buffer[l]); } } loc = strlen (str); str[loc-1] = '\n'; fwrite (str, 1, loc, fd_tar); addr1 += (remains_16 << 2); } } } fwrite ("\n", 1, 1, fd_tar); return 0; } int CUnasmARMDlg::dis_arm (FILE * fd_src, FILE * fd_tar, long addr, long addr1, long addr2) { long bytes; int i, bytes1; char src_buffer[16384]; int op_type; long cur_addr = addr + addr1; CrLf = 0; i = fseek (fd_src, addr1, SEEK_SET); bytes = (addr2 - addr1 + 1) & (~3); while (bytes > 0) { bytes1 = (bytes <= 16384) ? bytes : 16384; bytes -= bytes1; i = fread ( src_buffer, 1, bytes1, fd_src); if (i > 0) { //Dis-asm from src_buffer[0] , bytes1 bytes for (i = 0; i < bytes1; i += 4) { if (m_Radio1) { op_type = dis_arm_one ( (unsigned char ) src_buffer[i], (unsigned char ) src_buffer[i+1], (unsigned char ) src_buffer[i+2], (unsigned char ) src_buffer[i+3]); do_dis_arm (fd_src, fd_tar, cur_addr, addr, op_type, (unsigned char) src_buffer[i], (unsigned char) src_buffer[i+1], (unsigned char) src_buffer[i+2], (unsigned char) src_buffer[i+3]); } else { op_type = dis_arm_one ( (unsigned char ) src_buffer[i+3], (unsigned char ) src_buffer[i+2], (unsigned char ) src_buffer[i+1], (unsigned char ) src_buffer[i]); do_dis_arm (fd_src, fd_tar, cur_addr, addr, op_type, (unsigned char) src_buffer[i+3], (unsigned char) src_buffer[i+2], (unsigned char) src_buffer[i+1], (unsigned char) src_buffer[i]); } cur_addr += 4; } } } if (CrLf) CrLf = 0; else fwrite ("\n", 1, 1, fd_tar); return 0; } int CUnasmARMDlg::dis_thumb (FILE * fd_src, FILE * fd_tar, long addr, long addr1, long addr2) { int i, j, i_delta; long bytes; int bytes1; int remains; char temp, src_buffer[16384]; int op_type; long cur_addr = addr + addr1; CrLf = 0; i = fseek (fd_src, addr1, SEEK_SET); bytes = (addr2 - addr1 + 1) & (~1); remains = 0; while (bytes > 0) { bytes1 = (bytes <= 16384) ? bytes : 16384; if (remains && (bytes1 > 16382) ) bytes1 -= remains; bytes -= bytes1; i = fread ( &src_buffer[remains], 1, bytes1, fd_src); if (i > 0) { if (!m_Radio1) { for (j = 0; j < bytes1; j += 2) { temp = src_buffer[j]; src_buffer[j] = src_buffer[j+1]; src_buffer[j+1] = temp; } } //Dis-asm from src_buffer[0] , (bytes1+remains) bytes for (i = 0; i < bytes1 + remains; i += i_delta) { op_type = dis_thumb_one ( (unsigned char *) & src_buffer[i]); if (op_type != 19) { i_delta = 2; do_dis_thumb (fd_src, fd_tar, cur_addr, addr, op_type, (unsigned char) src_buffer[i], (unsigned char) src_buffer[i+1]); cur_addr += 2; } else { i_delta = 4; if ( (bytes1 + remains - i) < 4) { remains = 2; src_buffer[0] = src_buffer[i]; src_buffer[1] = src_buffer[i+1]; break; } else { int offset; char str[128], temp[128]; int TooBad = 0; if ( (src_buffer[i] & 8) == 0) { if ( (src_buffer[i+2] & 0xf8) != 0xf8) TooBad = 1; } else TooBad = 1; if (TooBad) { i_delta = 2; do_dis_thumb (fd_src, fd_tar, cur_addr, addr, 19, (unsigned char) src_buffer[i], (unsigned char) src_buffer[i+1]); cur_addr += 2; continue; } offset = (src_buffer[i+3] & 0xff) | ( (src_buffer[i+2] & 7) << 8) | ( (src_buffer[i+1] & 0xff) << 11) | ( (src_buffer[i] & 7) << 19); if (offset & 0x200000) { ( (unsigned char *) &offset) [3] = 0xff; ( (unsigned char *) &offset) [2] |= 0xc0; } offset = cur_addr + (offset << 1) + 4; if (m_Hex) { sprintf (str, "%08x %02X%02X%02X%02X ", cur_addr, 0xff & src_buffer[i], 0xff & src_buffer[i+1], 0xff & src_buffer[i+2], 0xff & src_buffer[i+3]); } else { sprintf (str, "%08x ", cur_addr); } sprintf (temp, "BL 0x%08x\n", offset); regNo = -1; strcat (str, temp); fwrite (str, 1, strlen (str), fd_tar); cur_addr += 4; } } } if (i_delta == 2) remains = 0; } } if (CrLf) CrLf = 0; else fwrite ("\n", 1, 1, fd_tar); return 0; } int CUnasmARMDlg::dis_thumb_one (unsigned char * bin_code) { unsigned uch; int op_type; //1-19 uch = bin_code[0] & 0xf0; // 1111 0000 switch (uch) { case 0x00: op_type = 1; // Move shifted register break; case 0x10: if ( (bin_code[0] & 0xf8) == 0x18) op_type = 2; // Add/substract else op_type = 1; // Move shifted register break; case 0x20: case 0x30: op_type = 3; // Move/compare/add/substract imm break; case 0x40: if ( (bin_code[0] & 0xfc) == 0x40) { op_type = 4; // ALU operations break; } if ( (bin_code[0] & 0xfc) == 0x44) { op_type = 5; // Hi register operation/Branch exchange break; } op_type = 6; // PC-relative load break; case 0x50: if ( (bin_code[0] & 0xf2) == 0x52) op_type = 8; // Load/store sign-exted byte/hw else op_type = 7; // Load/store with register offset break; case 0x60: case 0x70: op_type = 9; // Load/store with imm offset break; case 0x80: op_type = 10; // Load/store halfword break; case 0x90: op_type = 11; // SP-relative load/store break; case 0xa0: op_type = 12; // Load address break; case 0xb0: if (bin_code[0] == 0xb0) op_type = 13; // Add offset to stack pointer else op_type = 14; // Push/pop registers break; case 0xc0: op_type = 15; // Multiple load/store break; case 0xd0: if (bin_code[0] == 0xdf) op_type = 17; // Software interrupt else op_type = 16; // Conditional branch break; case 0xe0: op_type = 18; // Unconditional branch break; case 0xf0: op_type = 19; // Long branch with link break; } return op_type; } int CUnasmARMDlg::do_dis_thumb (FILE * fd_src, FILE * fd_tar, long addr, long start, int op_type, unsigned char byte1, unsigned char byte2) { char fourbytes[4], str[128]; unsigned long tar_addr; char temp[128]; int op, Rd, Rs, Rn, Ro, Rb, offset5, Cond, LB, HS; char *op_name = {"MOV CMP ADD SUB "}; char *op_name1 = {"AND EOR LSL LSR ASR ADC SBC ROR TST NEG CMP CMN ORR MUL BIC MVN "}; char *op_name2 = {"LSL LSR ASR "}; char *cond_name = {"BEQ BNE BCS BCC BMI BPL BVS BVC BHI BLS BGE BLT BGT BLE "}; char *op_name3 = {"STR STRBLDR LDRB"}; char *op_name4 = {"STRHLDSBLDRHLDSH"}; char *op_name5 = {"STR LDR STRBLDRB"}; char *op_name6 = {"ADD CMP MOV BX "}; long cur_loc; int len; CrLf = 0; if (m_Hex) { sprintf (str, "%08x %02X%02X ", addr, byte1, byte2); } else { sprintf (str, "%08x ", addr); } switch (op_type) { case 1: op = (byte1 & 0x18) >> 3; memcpy (temp, &op_name2[op << 2], 4); temp[4] = '\0'; strcat (temp, " "); offset5 = ( (byte1 & 7) << 2) | ( (byte2 & 0xc0) >> 6); if (op) { if (offset5 == 0) offset5 = 32; } Rd = byte2 & 7; Rs = (byte2 & 0x38) >> 3; if (Rd != Rs) { sprintf (&temp[8], "R%d, R%d, #%d", Rd, Rs, offset5); if ( (Rs == regNo) && (!op) ) { len = strlen (temp); if (offset5 < 10) sprintf (&temp[len], " ;%08x", regValue << offset5); else sprintf (&temp[len], " ;%08x", regValue << offset5); } } else { sprintf (&temp[8], "R%d, #%d", Rd, offset5); if ( (Rs == regNo) && (!op) ) { len = strlen (temp); if (offset5 < 10) sprintf (&temp[len], " ;%08x", regValue << offset5); else sprintf (&temp[len], " ;%08x", regValue << offset5); } } regNo = -1; strcat (str, temp); break; case 2: Rn = ( (byte1 & 1) << 2) | ( (byte2 & 0xc0) >> 6); Rd = byte2 & 7; Rs = (byte2 & 0x38) >> 3; if (byte1 & 2) strcpy (temp, "SUB "); else strcpy (temp, "ADD "); if (byte1 & 4) { // Immediate operation if (Rn == 0) { temp[0] = 'M'; // ADD rd, rs, #0 -> MOV rd, rs temp[1] = 'O'; temp[2] = 'V'; sprintf (&temp[8], "R%d, R%d", Rd, Rs); } else { sprintf (&temp[8], "R%d, R%d, #%d", Rd, Rs, Rn); } } else { // Register operation sprintf (&temp[8], "R%d, R%d, R%d", Rd, Rs, Rn); } regNo = -1; strcat (str, temp); break; case 3: op = (byte1 & 0x18) >> 3; memcpy (temp, &op_name[op << 3], 8); Rd = byte1 & 7; if ( (Rd == 15) && (op == 0) ) CrLf = 1; if (byte2 > 9) sprintf (&temp[8], "%s, #0x%02x", RegisterName[Rd], byte2); else sprintf (&temp[8], "%s, #%d", RegisterName[Rd], byte2); if (!op) { regNo = Rd; regValue = byte2; } if (op == 2) { if (Rd == regNo) { len = strlen (temp); if (byte2 > 9) sprintf (&temp[len], " ;%08x", regValue + byte2); else sprintf (&temp[len], " ;%08x", regValue + byte2); regNo = -1; } } strcat (str, temp); break; case 4: op = ( (byte1 & 3) << 2) | ( (byte2 & 0xc0) ) >> 6; memcpy (temp, &op_name1[op << 2], 4); temp[4] = '\0'; strcat (temp, " "); Rd = byte2 & 7; Rs = (byte2 & 0x38) >> 3; sprintf (&temp[8], "R%d, R%d", Rd, Rs); regNo = -1; strcat (str, temp); break; case 5: op = byte1 & 3; memcpy (temp, &op_name6[op << 2], 4); temp[4] = '\0'; strcat (temp, " "); if (op == 3) { // BX Rs = (byte2 & 0x38) >> 3; HS = ( (byte2 & 0xc0) >> 6) & 3; if (HS == 1) Rs += 8; sprintf (temp, "BX %s", RegisterName[Rs]); CrLf = 1; } else { Rs = (byte2 & 0x38) >> 3; Rd = byte2 & 7; HS = ( (byte2 & 0xc0) >> 6) & 3; if (HS == 0) { strcat (temp, "??????"); } else { if (HS == 1) Rs += 8; if (HS == 2) Rd += 8; if (HS == 3) { Rs += 8; Rd += 8; } if ( (Rd == 15) && (op == 2) ) // MOV PC, ... CrLf = 1; sprintf (&temp[8], "%s, %s", RegisterName[Rd], RegisterName[Rs]); } } strcat (str, temp); regNo = -1; break; case 6: float f; Rd = byte1 & 7; tar_addr = ( (byte2 << 2) + addr + 4) & 0xfffffffc; cur_loc = ftell (fd_src); fseek (fd_src, tar_addr - start, SEEK_SET); fread ( fourbytes, 1, 4, fd_src); fseek (fd_src, cur_loc, SEEK_SET); if (Rd < 10) { if ( (unsigned) fourbytes[0] >= '0') { if (m_Radio1) { ( (char *) (&f) ) [0] = fourbytes[3]; ( (char *) (&f) ) [1] = fourbytes[2]; ( (char *) (&f) ) [2] = fourbytes[1]; ( (char *) (&f) ) [3] = fourbytes[0]; sprintf (temp, "LDR R%d, 0x%08x ;%02x%02x%02x%02x(%g)", Rd, tar_addr, 0xff & fourbytes[0], 0xff & fourbytes[1], 0xff & fourbytes[2], 0xff & fourbytes[3], f); } else { ( (char *) (&f) ) [0] = fourbytes[0]; ( (char *) (&f) ) [1] = fourbytes[1]; ( (char *) (&f) ) [2] = fourbytes[2]; ( (char *) (&f) ) [3] = fourbytes[3]; sprintf (temp, "LDR R%d, 0x%08x ;%02x%02x%02x%02x(%g)", Rd, tar_addr, 0xff & fourbytes[3], 0xff & fourbytes[2], 0xff & fourbytes[1], 0xff & fourbytes[0], f); } } else { if (m_Radio1) { sprintf (temp, "LDR R%d, 0x%08x ;%02x%02x%02x%02x", Rd, tar_addr, 0xff & fourbytes[0], 0xff & fourbytes[1], 0xff & fourbytes[2], 0xff & fourbytes[3]); } else { sprintf (temp, "LDR R%d, 0x%08x ;%02x%02x%02x%02x", Rd, tar_addr, 0xff & fourbytes[3], 0xff & fourbytes[2], 0xff & fourbytes[1], 0xff & fourbytes[0]); } } } else { if ( (unsigned) fourbytes[0] >= '0') { if (m_Radio1) { ( (char *) (&f) ) [0] = fourbytes[3]; ( (char *) (&f) ) [1] = fourbytes[2]; ( (char *) (&f) ) [2] = fourbytes[1]; ( (char *) (&f) ) [3] = fourbytes[0]; sprintf (temp, "LDR R%d, 0x%08x ;%02x%02x%02x%02x(%g)", Rd, tar_addr, 0xff & fourbytes[0], 0xff & fourbytes[1], 0xff & fourbytes[2], 0xff & fourbytes[3], f); } else { ( (char *) (&f) ) [0] = fourbytes[0]; ( (char *) (&f) ) [1] = fourbytes[1]; ( (char *) (&f) ) [2] = fourbytes[2]; ( (char *) (&f) ) [3] = fourbytes[3]; sprintf (temp, "LDR R%d, 0x%08x ;%02x%02x%02x%02x(%g)", Rd, tar_addr, 0xff & fourbytes[3], 0xff & fourbytes[2], 0xff & fourbytes[1], 0xff & fourbytes[0], f); } } else { if (m_Radio1) { sprintf (temp, "LDR R%d, 0x%08x ;%02x%02x%02x%02x", Rd, tar_addr, 0xff & fourbytes[0], 0xff & fourbytes[1], 0xff & fourbytes[2], 0xff & fourbytes[3]); } else { sprintf (temp, "LDR R%d, 0x%08x ;%02x%02x%02x%02x", Rd, tar_addr, 0xff & fourbytes[3], 0xff & fourbytes[2], 0xff & fourbytes[1], 0xff & fourbytes[0]); } } } strcat (str, temp); regNo = -1; break; case 7: LB = (byte1 & 0x0c) >> 2; Ro = ( (byte1 & 1) << 2) | ( (byte2 & 0xc0) >> 6); Rd = byte2 & 7; Rb = (byte2 & 0x38) >> 3; memcpy (temp, &op_name3[LB << 2], 4); temp[4] = '\0'; strcat (temp, " "); sprintf (&temp[8], "R%d, [R%d, R%d]", Rd, Rb, Ro); strcat (str, temp); regNo = -1; break; case 8: HS = (byte1 & 0x0c) >> 2; Ro = ( (byte1 & 1) << 2) | ( (byte2 & 0xc0) >> 6); Rd = byte2 & 7; Rb = (byte2 & 0x38) >> 3; memcpy (temp, &op_name4[HS << 2], 4); temp[4] = '\0'; strcat (temp, " "); sprintf (&temp[8], "R%d, [R%d, R%d]", Rd, Rb, Ro); strcat (str, temp); regNo = -1; break; case 9: LB = (byte1 & 0x18) >> 3; offset5 = ( (byte1 & 7) << 2) | ( (byte2 & 0xc0) >> 6); Rd = byte2 & 7; Rb = (byte2 & 0x38) >> 3; memcpy (temp, &op_name5[LB << 2], 4); temp[4] = '\0'; strcat (temp, " "); if (LB < 2) { // WORD sprintf (&temp[8], "R%d, [R%d, #0x%02x]", Rd, Rb, offset5 << 2); } else { sprintf (&temp[8], "R%d, [R%d, #0x%02x]", Rd, Rb, offset5); } strcat (str, temp); regNo = -1; break; case 10: offset5 = ( (byte1 & 7) << 2) | ( (byte2 & 0xc0) >> 6); Rd = byte2 & 7; Rb = (byte2 & 0x38) >> 3; if (byte1 & 8) strcpy (temp, "LDRH "); else strcpy (temp, "STRH "); sprintf (&temp[8], "R%d, [R%d, #0x%02x]", Rd, Rb, offset5 << 1); strcat (str, temp); regNo = -1; break; case 11: if (byte1 & 8) // LOAD strcpy (temp, "LDR "); else strcpy (temp, "STR "); Rd = byte1 & 7; sprintf (&temp[8], "R%d, [R13, #0x%02x]", Rd, byte2 << 2); strcat (str, temp); regNo = -1; break; case 12: Rd = byte1 & 7; if (byte1 & 8) sprintf (temp, "ADD R%d, SP, #0x%02x", Rd, byte2 << 2); else { sprintf (temp, "ADR R%d, 0x%08x", Rd, ( (byte2 << 2) + addr + 4) & ~3); } strcat (str, temp); regNo = -1; break; case 13: if (byte2 & 0x80) { sprintf (temp, "SUB SP, #0x%02x", (byte2 & 0x7f) << 2); } else { sprintf (temp, "ADD SP, #0x%02x", (byte2 & 0x7f) << 2); } strcat (str, temp); regNo = -1; break; case 14: if (byte1 & 8) strcpy (temp, "POP {"); else strcpy (temp, "PUSH {"); LB = strlen (temp); if (byte2) { offset5 = byte2; for (op = 0; op < 8; op++) { if (offset5 & 1) { temp[LB++] = 'R'; temp[LB++] = op + '0'; temp[LB++] = ','; } offset5 >>= 1; } LB--; // Discard ',' } if (byte1 & 1) { if (byte2) temp[LB++] = ','; if (byte1 & 8) { // POP {Rlist, PC} temp[LB++] = 'P'; temp[LB++] = 'C'; CrLf = 1; } else { // PUSH {Rlist, LR} temp[LB++] = 'L'; temp[LB++] = 'R'; } } temp[LB++] = '}'; temp[LB] = '\0'; strcat (str, temp); regNo = -1; break; case 15: if (byte1 & 8) strcpy (temp, "LDMIA "); else strcpy (temp, "STMIA "); Rb = byte1 & 7; sprintf (&temp[8], "R%d!, {", Rb); LB = strlen (temp); if (byte2) { offset5 = byte2; for (op = 0; op < 8; op++) { if (offset5 & 1) { temp[LB++] = 'R'; temp[LB++] = op + '0'; temp[LB++] = ','; } offset5 >>= 1; } LB--; // Discard ',' } temp[LB++] = '}'; temp[LB] = '\0'; strcat (str, temp); regNo = -1; break; case 16: Cond = (byte1 & 0x0f); if (byte2 & 0x80) { offset5 = byte2; ( (unsigned char *) &offset5) [1] = 0xff; ( (unsigned char *) &offset5) [2] = 0xff; ( (unsigned char *) &offset5) [3] = 0xff; tar_addr = addr + 4 + (offset5 << 1); } else tar_addr = (byte2 << 1) + addr + 4; memcpy (temp, &cond_name[Cond << 2], 4); sprintf (&temp[4], " 0x%08x", tar_addr); strcat (str, temp); regNo = -1; break; case 17: sprintf (temp, "SWI 0x%02x", byte2); strcat (str, temp); regNo = -1; break; case 18: offset5 = ( (byte1 & 0x7) << 8) | byte2; if (offset5 & 0x400) { ( (unsigned char *) &offset5) [1] |= 0xf8; ( (unsigned char *) &offset5) [2] = 0xff; ( (unsigned char *) &offset5) [3] = 0xff; } tar_addr = (offset5 << 1) + addr + 4; sprintf (temp, "B 0x%08x", tar_addr); strcat (str, temp); regNo = -1; break; case 19: strcpy (temp, "?????? ; Bad statement"); strcat (str, temp); regNo = -1; break; } strcat (str, "\n"); fwrite (str, 1, strlen (str), fd_tar); if (CrLf) fwrite ("\n", 1, 1, fd_tar); return 0; } int CUnasmARMDlg::dis_arm_one (unsigned char bin_code1, unsigned char bin_code2, unsigned char bin_code3, unsigned char bin_code4) { unsigned uch1, uch4; int op_type; // 1-15 uch1 = bin_code1 & 0x0f; // 0000 1111 uch4 = bin_code4 & 0xf0; // 1111 0000 if (uch1 == 1) { if ( (bin_code2 == 0x2f) && (bin_code3 == 0xff) && (uch4 == 0x10) ) return 5; else { if ( (uch4 == 0x90) && ( (bin_code3 & 15) == 0) ) return 4; } } if ( (uch1 == 0) && (uch4 == 0x90) ) { if (bin_code2 & 0x80) return 3; else return 2; } if ( (uch1 == 0) || (uch1 == 1) ) { if ( (uch4 & 0x90) == 0x90) { if ( (bin_code2 & 0x40) == 0x40) return 7; else { if ( (bin_code3 & 15) == 0) return 6; } } } if (uch1 < 4) { if ( (uch1 == 1) && ( (bin_code2 & 0xbf) == 0x0f) && (bin_code4 == 0) && ( (bin_code3 & 0x0f) == 0) ) return 16; if ( (uch1 == 1) && ( (bin_code2 & 0xb0) == 0x20) && (bin_code3 == 0xf0) && (uch4 == 0) ) return 17; if ( ( (uch1 & 0x0d) == 1) && ( (bin_code2 & 0xb0) == 0x20) && ( (bin_code3 & 0xf0) == 0xf0) ) return 18; else return 1; } if (uch1 < 8) { if ( ( (uch4 & 0x10) == 0x10) && ( (uch1 & 6) == 6) ) return 9; else return 8; } if (uch1 == 15) return 15; if (uch1 == 14) { if ( (uch4 & 0x10) == 0x10) return 14; else return 13; } op_type = (uch1 >> 1) + 6; return op_type; } int CUnasmARMDlg::do_dis_arm (FILE * fd_src, FILE * fd_tar, long addr, long start, int op_type, unsigned char byte1, unsigned char byte2, unsigned char byte3, unsigned char byte4) { char fourbytes[4], str[128]; char temp[128]; int loc, sft_type; int Opcode, Rn, Rd, Rm, Rs, RdLo, RdHi, CP; unsigned int ImmValue; int offset; long cur_loc; int cond; char *cond_name = {"EQNECSCCMIPLVSVCHILSGELTGTLE"}; /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ char *op_name1 = {"AND EOR SUB RSB ADD ADC SBC RSC TST TEQ CMP CMN ORR MOV BIC MVN "}; // For LDM/STM int LPU; char *op_name; char *op_name2 = {"EDEAFDFAFAFDEAED"}; // Stack char *op_name3 = {"DAIADBIBDAIADBIB"}; // Other // For LDRH/... int SH; char *op_name4 = {"LDRH LDRSB LDRSH "}; char *Sft_name = {"lsl lsr asr ror "}; if (m_Hex) { sprintf (str, "%08x %02X%02X%02X%02X ", addr, byte1, byte2, byte3, byte4); } else { sprintf (str, "%08x ", addr); } cond = byte1 >> 4; CrLf = 0; switch (op_type) { case 1: Opcode = ( (byte1 & 1) << 3) | (byte2 >> 5); memcpy (temp, &op_name1[Opcode << 2], 4); temp[4] = '\0'; strcat (temp, " "); Rn = byte2 & 15; Rd = byte3 >> 4; if (byte1 & 2) { // Operand 2 is an imm value ImmValue = ROR (byte4, byte3 & 15); if ( (Opcode == 13) || (Opcode == 15) ) { sprintf (&temp[8], "%s, #0x%-x", RegisterName[Rd], ImmValue); } else { if ( (Opcode >= 8) && (Opcode <= 11) ) { sprintf (&temp[8], "%s, #0x%-x", RegisterName[Rn], ImmValue); } else { sprintf (&temp[8], "%s, %s, #0x%-x", RegisterName[Rd], RegisterName[Rn], ImmValue); } } } else { // Operand 2 is a register Rm = byte4 & 15; if ( (Opcode >= 8) && (Opcode <= 11) ) { sprintf (&temp[8], "%s, ", RegisterName[Rn]); } else { if ( (Opcode == 13) || (Opcode == 15) ) { sprintf (&temp[8], "%s, ", RegisterName[Rd]); } else { sprintf (&temp[8], "%s, %s, ", RegisterName[Rd], RegisterName[Rn]); } } loc = strlen (temp); sprintf (&temp[loc], "%s, ", RegisterName[Rm]); sft_type = (byte4 >> 5) & 3; loc = strlen (temp); memcpy (&temp[loc], &Sft_name[sft_type << 2], 4); loc += 4; if (byte4 & 0x10) { Rs = byte3 & 15; sprintf (&temp[loc], "%s", RegisterName[Rs]); } else { Rs = ( (byte3 & 15) << 1) | ( (byte4 & 0x80) >> 7); if (Rs == 0) { if (/*(Opcode != 13) && */sft_type) { // not MOV if (sft_type == 3) { // ror loc -= 4; // ror #0 -> rrx strcpy (&temp[loc], "RRX"); } else strcpy (&temp[loc], "#32"); } else { loc -= 6; // MOV temp[loc] = '\0'; } } else sprintf (&temp[loc], "#%d", Rs); } } if (byte2 & 0x10) { // Set Condition codes if (cond < 14) { // Conditional cond <<= 1; temp[3] = cond_name[cond]; temp[4] = cond_name[cond+1]; temp[5] = ( (Opcode >= 8) && (Opcode <= 11) ) ? ' ' : 'S'; } else { temp[3] = ( (Opcode >= 8) && (Opcode <= 11) ) ? ' ' : 'S'; } } else { if (cond < 14) { // Conditional cond <<= 1; temp[3] = cond_name[cond]; temp[4] = cond_name[cond+1]; } } strcat (str, temp); break; case 2: Rd = byte2 & 15; Rn = byte3 >> 4; Rs = byte3 & 15; Rm = byte4 & 15; if (byte2 & 0x20) sprintf (temp, "MLA R%d, R%d, R%d, R%d", Rd, Rm, Rs, Rn); else sprintf (temp, "MUL R%d, R%d, R%d", Rd, Rm, Rs); if (cond < 14) { // Conditional cond <<= 1; temp[3] = cond_name[cond]; temp[4] = cond_name[cond+1]; loc = 5; } else loc = 3; if (byte2 & 0x10) temp[loc] = 'S'; strcat (str, temp); break; case 3: RdHi = byte2 & 15; RdLo = byte3 >> 4; Rs = byte3 & 15; Rm = byte4 & 15; if (byte2 & 0x20) { sprintf (temp, "%cMLAL R%d, R%d, R%d, R%d", (byte2 & 0x40) ? 'S' : 'U', RdLo, RdHi, Rm, Rs); } else { sprintf (temp, "%cMULL R%d, R%d, R%d, R%d", (byte2 & 0x40) ? 'S' : 'U', RdLo, RdHi, Rm, Rs); } if (cond < 14) { // Conditional cond <<= 1; temp[5] = cond_name[cond]; temp[6] = cond_name[cond+1]; loc = 7; } else loc = 5; if (byte2 & 0x10) temp[loc] = 'S'; strcat (str, temp); break; case 4: Rn = byte2 & 15; Rd = byte3 >> 4; Rm = byte4 & 15; sprintf (temp, "SWP R%d, R%d, [R%d]", Rd, Rm, Rn); if (cond < 14) { // Conditional cond <<= 1; temp[3] = cond_name[cond]; temp[4] = cond_name[cond+1]; loc = 5; } else loc = 3; if (byte2 & 0x40) temp[loc] = 'B'; strcat (str, temp); break; case 5: Rn = byte4 & 15; sprintf (temp, "BX %s", RegisterName[Rn]); if (cond < 14) { // Conditional cond <<= 1; temp[2] = cond_name[cond]; temp[3] = cond_name[cond+1]; } strcat (str, temp); CrLf = 1; break; case 6: Rn = byte2 & 15; Rd = byte3 >> 4; Rm = byte4 & 15; SH = (byte4 >> 5) & 3; if (SH == 0) { strcat (str, "Bad SH!"); break; } SH = (SH - 1) << 3; if (byte2 & 0x10) { // Load memcpy (temp, &op_name4[SH], 8); } else { // Store strcpy (temp, "STRH "); } if (byte1 & 1) { // Pre sprintf (&temp[8], "R%d, [R%d, %cR%d]%c", Rd, Rn, (byte2 & 0x80) ? ' ' : '-', Rm, (byte2 & 0x20) ? '!' : ' '); } else { sprintf (&temp[8], "R%d, [R%d], %cR%d", Rd, Rn, (byte2 & 0x80) ? ' ' : '-', Rm); } if (cond < 14) { // Conditional cond <<= 1; temp[6] = temp[4]; temp[5] = temp[3]; temp[3] = cond_name[cond]; temp[4] = cond_name[cond+1]; } strcat (str, temp); break; case 7: Rn = byte2 & 15; Rd = byte3 >> 4; offset = (byte4 & 15) | ( (byte3 << 4) & 0xf0); SH = (byte4 >> 5) & 3; if (SH == 0) { strcat (str, "Bad SH!"); break; } SH = (SH - 1) << 3; if (byte2 & 0x10) { // Load memcpy (temp, &op_name4[SH], 8); } else { // Store strcpy (temp, "STRH "); } if (byte1 & 1) { // Pre if (byte2 & 0x80) { sprintf (&temp[8], "R%d, [R%d, #0x%-x]%c", Rd, Rn, offset, (byte2 & 0x20) ? '!' : ' '); } else { sprintf (&temp[8], "R%d, [R%d, #-0x%-x]%c", Rd, Rn, offset, (byte2 & 0x20) ? '!' : ' '); } } else { if (byte2 & 0x80) { sprintf (&temp[8], "R%d, [R%d], #0x%0x", Rd, Rn, offset); } else { sprintf (&temp[8], "R%d, [R%d], #-0x%0x", Rd, Rn, offset); } } if (cond < 14) { // Conditional cond <<= 1; temp[6] = temp[4]; temp[5] = temp[3]; temp[3] = cond_name[cond]; temp[4] = cond_name[cond+1]; } strcat (str, temp); break; case 8: if (byte2 & 0x10) strcpy (temp, "LDR "); else strcpy (temp, "STR "); if (byte2 & 0x40) temp[3] = 'B'; Rn = byte2 & 15; Rd = byte3 >> 4; sprintf (&temp[8], "R%d, [R%d", Rd, Rn); loc = strlen (temp); if (byte1 & 1) { // Pre if (byte1 & 2) { // offset is a register temp[loc++] = ','; temp[loc++] = ' '; Rm = byte4 & 15; if ( (byte2 & 0x80) == 0) { temp[loc++] = '-'; } sprintf (&temp[loc], "R%d, ", Rm); sft_type = (byte4 >> 5) & 3; loc = strlen (temp); memcpy (&temp[loc], &Sft_name[sft_type << 2], 4); loc += 4; Rs = ( (byte3 & 15) << 1) | ( (byte4 & 0x80) >> 7); if (Rs == 0) { loc -= 6; temp[loc++] = ']'; temp[loc] = '\0'; } else sprintf (&temp[loc], "#%d]", Rs); } else { // offset is imm value offset = byte4 | ( (byte3 & 15) << 8); if (Rn == 15) { // PC loc -= 4; cur_loc = ftell (fd_src); if (byte2 & 0x80) { sprintf (&temp[loc], "0x%08x", addr + offset + 8); fseek (fd_src, addr + offset + 8 - start, SEEK_SET); } else { sprintf (&temp[loc], "0x%08x", addr - offset + 8); fseek (fd_src, addr - offset + 8 - start, SEEK_SET); } fread ( fourbytes, 1, 4, fd_src); fseek (fd_src, cur_loc, SEEK_SET); loc = strlen (temp); if (Rd < 10) { if (m_Radio1) { sprintf (&temp[loc], " ;%02x%02x%02x%02x", 0xff & fourbytes[0], 0xff & fourbytes[1], 0xff & fourbytes[2], 0xff & fourbytes[3]); } else { sprintf (&temp[loc], " ;%02x%02x%02x%02x", 0xff & fourbytes[3], 0xff & fourbytes[2], 0xff & fourbytes[1], 0xff & fourbytes[0]); } } else { if (m_Radio1) { sprintf (&temp[loc], " ;%02x%02x%02x%02x", 0xff & fourbytes[0], 0xff & fourbytes[1], 0xff & fourbytes[2], 0xff & fourbytes[3]); } else { sprintf (&temp[loc], " ;%02x%02x%02x%02x", 0xff & fourbytes[3], 0xff & fourbytes[2], 0xff & fourbytes[1], 0xff & fourbytes[0]); } } if (cond < 14) { // Conditional cond <<= 1; temp[6] = temp[4]; temp[5] = temp[3]; temp[3] = cond_name[cond]; temp[4] = cond_name[cond+1]; } strcat (str, temp); break; } if (offset == 0) { temp[loc++] = ']'; temp[loc] = '\0'; } else { if ( (byte2 & 0x80) == 0) sprintf (&temp[loc], ", #-0x%-x]", offset); else sprintf (&temp[loc], ", #0x%-x]", offset); } } if (byte2 & 0x20) { // write-back loc = strlen (temp); temp[loc++] = '!'; temp[loc] = '\0'; } } else { // Post temp[loc++] = ']'; if (byte1 & 2) { // offset is a register Rm = byte4 & 15; temp[loc++] = ','; temp[loc++] = ' '; if ( (byte2 & 0x80) == 0) temp[loc++] = '-'; sprintf (&temp[loc], "R%d, ", Rm); sft_type = (byte4 >> 5) & 3; loc = strlen (temp); memcpy (&temp[loc], &Sft_name[sft_type << 2], 4); loc += 4; Rs = ( (byte3 & 15) << 1) | ( (byte4 & 0x80) >> 7); if (Rs == 0) { loc -= 6; temp[loc] = '\0'; } else sprintf (&temp[loc], "#%d", Rs); } else { // offset is imm value offset = byte4 | ( (byte3 & 15) << 8); if (offset == 0) { temp[loc] = '\0'; } else { if ( (byte2 & 0x80) == 0) sprintf (&temp[loc], ", #-0x%-x", offset); else sprintf (&temp[loc], ", #0x%-x", offset); } } if (byte2 & 0x20) { // write-back if (temp[3] == 'B') temp[4] = 'T'; else temp[3] = 'T'; } } if (cond < 14) { // Conditional cond <<= 1; temp[6] = temp[4]; temp[5] = temp[3]; temp[3] = cond_name[cond]; temp[4] = cond_name[cond+1]; } strcat (str, temp); break; case 9: strcat (str, "Undefined instruction"); break; case 10: Rn = byte2 & 15; if (Rn == 13) op_name = op_name2; else op_name = op_name3; LPU = ( (byte1 & 1) << 1) | ( (byte2 >> 2) & 4) | ( (byte2 >> 7) & 1); if (LPU & 4) strcpy (temp, "LDM "); else strcpy (temp, "STM "); LPU <<= 1; temp[3] = op_name[LPU]; temp[4] = op_name[LPU+1]; sprintf (&temp[8], "R%d%c, {", Rn, (byte2 & 0x20) ? '!' : ' '); offset = ( (byte3 << 8) | byte4) & 0xffff; loc = strlen (temp); for (Opcode = 0; Opcode < 10; Opcode++) { if (offset & 1) { temp[loc++] = 'R'; temp[loc++] = Opcode + '0'; temp[loc++] = ','; } offset >>= 1; } for (Opcode = 10; Opcode < 16; Opcode++) { if (offset & 1) { if (Opcode == 15) { temp[loc++] = 'P'; temp[loc++] = 'C'; temp[loc++] = ','; if (temp[0] == 'L') // LDM CrLf = 1; } else { if (Opcode == 14) { temp[loc++] = 'L'; temp[loc++] = 'R'; temp[loc++] = ','; } else { temp[loc++] = 'R'; temp[loc++] = '1'; temp[loc++] = Opcode - 10 + '0'; temp[loc++] = ','; } } } offset >>= 1; } if (temp[loc-1] == ',') loc--; temp[loc++] = '}'; if (byte2 & 0x40) temp[loc++] = '^'; temp[loc] = '\0'; if (cond < 14) { // Conditional cond <<= 1; temp[6] = temp[4]; temp[5] = temp[3]; temp[3] = cond_name[cond]; temp[4] = cond_name[cond+1]; } strcat (str, temp); break; case 11: if (byte1 & 1) { // Branch with link strcpy (temp, "BL "); loc = 2; } else { strcpy (temp, "B "); loc = 1; } offset = byte4 | (byte3 << 8) | (byte2 << 16); if (byte2 & 0x80) // Sign extended ( (unsigned char *) &offset) [3] |= 0xff; offset = addr + 8 + (offset << 2); sprintf (&temp[8], "0x%08x", offset); if (cond < 14) { // Conditional cond <<= 1; temp[loc++] = cond_name[cond]; temp[loc] = cond_name[cond+1]; } strcat (str, temp); break; case 12: Rn = byte2 & 15; Rd = byte3 >> 4; CP = byte3 & 15; if (byte2 & 0x10) // Load strcpy (temp, "LDC "); else strcpy (temp, "STC "); if (byte2 & 0x40) temp[3] = 'N'; offset = byte4 << 2; if (byte1 & 1) { // Pre if (byte2 & 0x80) { sprintf (&temp[8], "P%d, C%d, [R%d, #0x%-x]%c", CP, Rd, Rn, offset, (byte2 & 0x20) ? '!' : ' '); } else { sprintf (&temp[8], "P%d, C%d, [R%d, #-0x%-x]%c", CP, Rd, Rn, offset, (byte2 & 0x20) ? '!' : ' '); } } else { if (byte2 & 0x80) { sprintf (&temp[8], "P%d, C%d, [R%d], #0x%-x", CP, Rd, Rn, offset); } else { sprintf (&temp[8], "P%d, C%d, [R%d], #-0x%-x", CP, Rd, Rn, offset); } } if (cond < 14) { // Conditional cond <<= 1; temp[5] = temp[3]; temp[3] = cond_name[cond]; temp[4] = cond_name[cond+1]; } strcat (str, temp); break; case 13: sprintf (temp, "CDP P%d, %d, C%d, C%d, C%d, %d", (byte3 & 15), (byte2 >> 4), (byte3 >> 4), (byte2 & 15), (byte4 & 15), (byte4 >> 5) ); if (cond < 14) { // Conditional cond <<= 1; temp[3] = cond_name[cond]; temp[4] = cond_name[cond+1]; } strcat (str, temp); break; case 14: if (byte2 & 0x10) strcpy (temp, "MRC "); else strcpy (temp, "MCR "); sprintf (&temp[8], "P%d, %d, R%d, C%d, C%d, %d", (byte3 & 15), (byte2 >> 5), (byte3 >> 4), (byte2 & 15), (byte4 & 15), (byte4 >> 5) ); if (cond < 14) { // Conditional cond <<= 1; temp[3] = cond_name[cond]; temp[4] = cond_name[cond+1]; } strcat (str, temp); break; case 15: sprintf (temp, "SWI 0x%02x%02x%02x", byte2, byte3, byte4); if (cond < 14) { // Conditional cond <<= 1; temp[3] = cond_name[cond]; temp[4] = cond_name[cond+1]; } strcat (str, temp); break; case 16: Rd = byte3 >> 4; if (byte2 & 0x40) sprintf (temp, "MRS R%d, SPSR", Rd); else sprintf (temp, "MRS R%d, CPSR", Rd); if (cond < 14) { // Conditional cond <<= 1; temp[3] = cond_name[cond]; temp[4] = cond_name[cond+1]; } strcat (str, temp); break; case 17: Rm = byte4 & 15; strcpy (temp, "MSR CPSR_"); if (byte2 & 0x40) temp[8] = 'S'; loc = strlen (temp); if (byte2 & 1) temp[loc++] = 'C'; if (byte2 & 2) temp[loc++] = 'X'; if (byte2 & 4) temp[loc++] = 'S'; if (byte2 & 8) temp[loc++] = 'F'; sprintf (&temp[loc], ", R%d", Rm); if (cond < 14) { // Conditional cond <<= 1; temp[3] = cond_name[cond]; temp[4] = cond_name[cond+1]; } strcat (str, temp); break; case 18: strcpy (temp, "MSR CPSR_"); if (byte2 & 0x40) temp[8] = 'S'; loc = strlen (temp); if (byte2 & 1) temp[loc++] = 'C'; if (byte2 & 2) temp[loc++] = 'X'; if (byte2 & 4) temp[loc++] = 'S'; if (byte2 & 8) temp[loc++] = 'F'; if (byte1 & 2) { // Operand 2 is an imm value ImmValue = ROR (byte4, byte3 & 15); sprintf (&temp[loc], ", #0x%-8x", ImmValue); } else { // Operand 2 is a register Rm = byte4 & 15; sprintf (&temp[loc], ", R%d", Rm); } if (cond < 14) { // Conditional cond <<= 1; temp[3] = cond_name[cond]; temp[4] = cond_name[cond+1]; } strcat (str, temp); break; default: sprintf (temp, "No=%d", op_type); strcat (str, temp); break; } strcat (str, "\n"); fwrite (str, 1, strlen (str), fd_tar); if (CrLf) fwrite ("\n", 1, 1, fd_tar); return 0; } unsigned long CUnasmARMDlg::ROR (unsigned char value, unsigned char rotate) { int i; unsigned int result = value; for ( i = 0; i < rotate << 1; i++) { if (result & 1) { result >>= 1; ( (unsigned char *) &result) [3] |= 0x80; } else result >>= 1; } return result; } void CUnasmARMDlg::OnButton1() { // TODO: Add your control notification handler code here int i; /* char sss[120]; unsigned short sss1[120]; memset(sss, 0, 120); sss1[0] = 0x542F; sss1[1] = 0x52A8; sss1[2] = 0x547C; sss1[3] = 0x53EB; sss1[4] = 0x8F6C; sss1[5] = 0x63A5; sss1[6] = 0x04ff; int iii = WideCharToMultiByte( CP_ACP, 0, sss1, 7, sss, 120, NULL, NULL); AfxMessageBox(sss); return; */ CFileDialog myFD (TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "BIN files (*.bin)|*.bin|All files (*.*)|*.*||"); i = myFD.DoModal(); if (i == IDOK) { m_filename1 = myFD.GetPathName(); UpdateData (FALSE); } } void CUnasmARMDlg::OnButton2() { // TODO: Add your control notification handler code here int i; CFileDialog myFD (TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Ref files (*.ref)|*.ref||"); i = myFD.DoModal(); if (i == IDOK) { m_filename2 = myFD.GetPathName(); UpdateData (FALSE); } } void CUnasmARMDlg::OnButton3() { // TODO: Add your control notification handler code here int i; CFileDialog myFD (FALSE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "ASM files (*.asm)|*.asm||"); i = myFD.DoModal(); if (i == IDOK) { m_filename3 = myFD.GetPathName(); UpdateData (FALSE); } } int CUnasmARMDlg::dump_byte_nochar (FILE * fd_src, FILE * fd_tar, long addr, long addr1, long addr2) { int i; long bytes; char src_buffer[16384]; i = fseek (fd_src, addr1, SEEK_SET); bytes = addr2 - addr1 + 1; while (bytes) { int loc, times_16, remains_16; int bytes1 = (bytes <= 16384) ? bytes : 16384; char str[128]; int k, l; if (addr1 & 15) { if ( (16 - (addr1 & 15) ) < bytes1) bytes1 = 16 - (addr1 & 15); } bytes -= bytes1; i = fread ( src_buffer, 1, bytes1, fd_src); if (i > 0) { bytes1 = i; // Bytes actually times_16 = bytes1 >> 4; remains_16 = bytes1 & 0x0f; l = 0; while (times_16) { sprintf (str, "%08x ", addr + addr1); for (k = 0; k < 16; k++, l++) { loc = strlen (str); sprintf (&str[loc], "%02X ", 0xff & src_buffer[l]); } str[33] = '-'; loc = strlen (str); str[loc-1] = '\n'; fwrite (str, 1, loc, fd_tar); times_16--; addr1 += 16; } if (remains_16) { memset (str, ' ', 128); sprintf (str, "%08x ", addr + addr1); for (k = 0; k < remains_16; k++, l++) { loc = strlen (str); sprintf (&str[loc], "%02X ", 0xff & src_buffer[l]); } loc = strlen (str); str[loc-1] = '\n'; if (remains_16 > 8) str[33] = '-'; fwrite (str, 1, loc, fd_tar); addr1 += remains_16; } } } fwrite ("\n", 1, 1, fd_tar); return 0; } int CUnasmARMDlg::dump_double (FILE * fd_src, FILE * fd_tar, long addr, long addr1, long addr2) { int i, l, bytes1; long bytes; char src_buffer[16384]; int loc, times_8; char str[128]; double theValue; i = fseek (fd_src, addr1, SEEK_SET); bytes = (addr2 - addr1 + 1) & ~7; while (bytes) { bytes1 = (bytes <= 16384) ? bytes : 16384; bytes -= bytes1; i = fread ( src_buffer, 1, bytes1, fd_src); if (i > 0) { times_8 = (i >> 3); for (i = 0, l = 0; i < times_8; i++, l += 8) { sprintf (str, "%08x ", addr + addr1); loc = strlen (str); if (m_Radio1) { ( (char *) &theValue) [0] = src_buffer[l+7]; ( (char *) &theValue) [1] = src_buffer[l+6]; ( (char *) &theValue) [2] = src_buffer[l+5]; ( (char *) &theValue) [3] = src_buffer[l+4]; ( (char *) &theValue) [4] = src_buffer[l+3]; ( (char *) &theValue) [5] = src_buffer[l+2]; ( (char *) &theValue) [6] = src_buffer[l+1]; ( (char *) &theValue) [7] = src_buffer[l]; sprintf (&str[loc], "%02X%02X%02X%02X%02X%02X%02X%02X ;%g\n", 0xff & src_buffer[l], 0xff & src_buffer[l+1], 0xff & src_buffer[l+2], 0xff & src_buffer[l+3], 0xff & src_buffer[l+4], 0xff & src_buffer[l+5], 0xff & src_buffer[l+6], 0xff & src_buffer[l+7], theValue); } else { ( (char *) &theValue) [0] = src_buffer[l]; ( (char *) &theValue) [1] = src_buffer[l+1]; ( (char *) &theValue) [2] = src_buffer[l+2]; ( (char *) &theValue) [3] = src_buffer[l+3]; ( (char *) &theValue) [4] = src_buffer[l+4]; ( (char *) &theValue) [5] = src_buffer[l+5]; ( (char *) &theValue) [6] = src_buffer[l+6]; ( (char *) &theValue) [7] = src_buffer[l+7]; sprintf (&str[loc], "%02X%02X%02X%02X%02X%02X%02X%02X ;%g\n", 0xff & src_buffer[l+7], 0xff & src_buffer[l+6], 0xff & src_buffer[l+5], 0xff & src_buffer[l+4], 0xff & src_buffer[l+3], 0xff & src_buffer[l+2], 0xff & src_buffer[l+1], 0xff & src_buffer[l], theValue); } fwrite (str, 1, strlen (str), fd_tar); addr1 += 8; } } } fwrite ("\n", 1, 1, fd_tar); return 0; } int CUnasmARMDlg::dump_float (FILE * fd_src, FILE * fd_tar, long addr, long addr1, long addr2) { int i, l, bytes1; long bytes; char src_buffer[16384]; int loc, times_4; char str[128]; float theValue; i = fseek (fd_src, addr1, SEEK_SET); bytes = (addr2 - addr1 + 1) & ~3; while (bytes) { bytes1 = (bytes <= 16384) ? bytes : 16384; bytes -= bytes1; i = fread ( src_buffer, 1, bytes1, fd_src); if (i > 0) { times_4 = (i >> 2); for (i = 0, l = 0; i < times_4; i++, l += 4) { sprintf (str, "%08x ", addr + addr1); loc = strlen (str); if (m_Radio1) { ( (char *) &theValue) [0] = src_buffer[l+3]; ( (char *) &theValue) [1] = src_buffer[l+2]; ( (char *) &theValue) [2] = src_buffer[l+1]; ( (char *) &theValue) [3] = src_buffer[l]; sprintf (&str[loc], "%02X%02X%02X%02X ;%g\n", 0xff & src_buffer[l], 0xff & src_buffer[l+1], 0xff & src_buffer[l+2], 0xff & src_buffer[l+3], theValue); } else { ( (char *) &theValue) [0] = src_buffer[l]; ( (char *) &theValue) [1] = src_buffer[l+1]; ( (char *) &theValue) [2] = src_buffer[l+2]; ( (char *) &theValue) [3] = src_buffer[l+3]; sprintf (&str[loc], "%02X%02X%02X%02X ;%g\n", 0xff & src_buffer[l+3], 0xff & src_buffer[l+2], 0xff & src_buffer[l+1], 0xff & src_buffer[l], theValue); } fwrite (str, 1, strlen (str), fd_tar); addr1 += 4; } } } fwrite ("\n", 1, 1, fd_tar); return 0; }
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏记录
参与人
雪币
留言
时间
Youlor
为你点赞~
2024-5-31 03:23
伟叔叔
为你点赞~
2024-2-14 00:09
QinBeast
为你点赞~
2024-1-16 04:16
shinratensei
为你点赞~
2024-1-10 00:11
心游尘世外
为你点赞~
2023-12-28 00:04
飘零丶
为你点赞~
2023-12-16 00:46
一笑人间万事
为你点赞~
2023-3-18 02:50
赞赏
他的文章
- 一种简单的Android全局注入方案 28163
- [分享]源码百度云加速 5061
- 定位Method的dalvik字节码 6055
- 测试 3900
- [讨论]上个看雪都被劫持了, 7415
看原图
赞赏
雪币:
留言: