⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unasmarmdlg.cpp

📁 VC写的一个可以对ARM进行反汇编的工具的原代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                        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];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -