首页
社区
课程
招聘
ARM反汇编
2010-8-29 21:27 9253

ARM反汇编

2010-8-29 21:27
9253
#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; 
} 

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
点赞6
打赏
分享
最新回复 (3)
雪    币: 478
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
flyingayi 2010-8-30 09:35
2
0
一个字:长。
雪    币: 563
活跃值: (95)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lixupeng 2010-10-2 16:01
3
0
收下了回去试试
雪    币: 121
活跃值: (22)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
salwtp 2010-10-3 11:03
4
0
哇 好长哦 翻得眼睛都花了
游客
登录 | 注册 方可回帖
返回