3

I'm trying to figure out the password that is used to access the U-Boot shell, as mentoined in my previous question.

I'm having trouble understanding how exactly the code works. Here is an image of the code from IDA. The part in the yellow box (loc_8080FF28) is what I don't understand. What is it doing to the user input? Also I would like to understand what the subroutine in the orange box (sub_8081ECE4) does with the user input. I have added a few comments that I thought are relevant. enter image description here

Here is the code in text form:

loc_8080FF10
ADD R4, R4, #1
LDR R0, =aDstInputPasswd ; "\n%dst input Passwd:"
MOV R5, #0
MOV R1, R4      ; R4 = num of tries so far
BL  printf
B   loc_8080FF58

loc_8080FF28
MOV R0, R5
MOV R1, #0x3F
BL  __aeabi_uidivmod
ADD R2, SP, #0x58+var_18
ADD R5, R5, #1
ADD R7, R1, R7
ADD R3, R2, R1
LDRB    R2, [R7,#0x14]
RSB R10, R2, R10
MOV R2, #0
STRB    R10, [R3,#-0x40]
STRB    R2, [R3,#-0x3F]

loc_8080FF58
BL  getc
LDR R7, =asc_8082E770 ; "\b \b"
UXTB    R10, R0
CMP R10, #0xD   ; check if enter pressed
BNE loc_8080FF28
MOV R0, SP
ADD R1, R7, #0x54
MOV R2, #7
BL  sub_8081ECE4
CMP R0, #0
BNE loc_8080FF94
CMP R5, #7
MOVEQ   R5, #1
MOVEQ   R4, R0
BEQ loc_8080FFC0

loc_8080FF94
CMP R4, #3
BNE loc_8080FF10    ; fail after 3 tries
MOV R5, #0
MOV R4, R5
B   loc_8080FFC0

loc_8080FFA8
MOV R0, #0x2710
ADD R7, R7, #1
BL  sub_8081F1D8
CMP R7, #0x64
BNE loc_8080FEEC
SUB R4, R4, #1

loc_8080FFC0        ; "\b\b\b%2d "
LDR R0, =a2d
MOV R1, R4
BL  printf
; end of check passwd

sub_8081ECE4
STMFD   SP!, {R4,LR}
MOV R3, #0
B   loc_8081ED18

loc_8081ECF0
LDRB    R4, [R0,R3]
LDRB    R12, [R1,R3]
RSB R12, R12, R4
UXTB    R12, R12
CMP R12, #0
BNE loc_8081ED24
CMP R4, #0
ADD R3, R3, #1
BEQ loc_8081ED24
SUB R2, R2, #1

loc_8081ED18
CMP R2, #0
BNE loc_8081ECF0
MOV R12, R2

loc_8081ED24
SXTB    R0, R12
LDMFD   SP!, {R4,PC}
; End of function sub_8081ECE4
1

routine sub_8081ECE4 seems to subtract 7 bytes from this address 0x8082e7c4 (R1=R7+0x54=0x8082e770+0x54) to data on the stack (I presume that is the entered password). Can you provide bytes @0x8082e7c4?

EDIT: The block with a yellow background is some sort of decryption routine, substracting entered char with a byte table @0x8082e770. You need to look closer at what happens on the stack around SP+0x58+var18, SP+0x54. Sub_8081ece4 is a strncmp function. I have more or less transcribed in C:

// strncmp
int sub_8081ece4(char*str1, char *str2, int count) {
    for(int i=count, int j=0; i > 0; --count; ++j) {
        int cmp = str1[j] - str2[j];
        if( cmp != 0 || str1[j] == 0)
            return cmp;
    }
    return 0;
}

//...
// from loc_8080ff58
int i = 0;
char ch;
char var_18[0x3f]; // 0x58+var_18
char *tab; // ptr to 0x8082e770
while((ch = getch()) != 0xD) {
    int mod = i % 0x3f;
    ++i;
    var_18[mod - 0x40] = ch - tab[mod + 0x14];
    var_18[mod - 0x3f] = 0;
}
5
  • The bytes look like this in disassembly view: 8082E7C4 DCD 0x22244C43, 0x30252B and in hex view: 43 4C 24 22 2B 25 30 00 – nyaol9 May 3 at 12:45
  • I tried to figure out what var_18 as it seems to be an argument to this function but it doesn't seem to have any value set. At the start of this function IDA shows it as var_18= -0x18. Also the bytes @0x8082e770 are a string "\b \b" so i'm not sure what to do with that either. I kind of managed to get the assembly code running in a debugger but it doesn't behave the same way as the original mainly because getc works differently. – nyaol9 May 4 at 18:33
  • It says tab[mod + 0x14], so you don't need to look at 0x8082e770, but at 0x8082e84. Also, var_18 is not passed to the function, but a local (uninitialized) variable, which will be initialized from the key presses and the obfuscation table. – Michael Karcher May 5 at 5:39
  • @MichaelKarcher did you mean 0x8082e784? IDA could not go to 0x8082e84. The bytes at 0x8082e784 are exactly 7 bytes of non-zero bytes (7 was also one of the inputs to strncmp) so that could be the table. I will try to figure it out and work with the C code written by Tony to get a password prompt similar to the original. Am I right in guessing that the password could be 7 characters long? I also need to figure out where the original password is stored so I could try to reverse it once I get the decrypt code figured out. – nyaol9 May 5 at 18:52
  • @nyaol9 Yes, sorry for the lost digit. It is very likely that the password is 7 characters (you may enter more, but the remaining characters get ignored - this is how strncmp works. It looks like the password is the bytewise sum of the bytes at 8082e784 and 8082e7c4 – Michael Karcher May 5 at 21:50
0

I have now managed to find the password.

Thanks to the C code provided by Tony in his answer and information provided by Michael in the comments, I was able to make a password prompt that was similar to the original and through that I was able to find the password with some trial and error.

I also tested the password on the actual hardware and was able to get into U-Boot shell.

Here is the C program for reference

#include <iostream>
#include <conio.h> // for getch

int main()
{
    int numOfTries = 1;

    char decTable[64] = { 0x23, 0x22, 0x02, 0x17, 0x0A, 0x0D, 0x07 }; // decryption table
    char passwd[8] = { 0x43, 0x4C, 0x24, 0x22, 0x2B, 0x25, 0x30, 0x0 }; // original, encrypted password

    // set rest of decTable to 0x0
    for (int j = 7; j < 64; j++)
        decTable[j] = 0x0;

    // reverse original password and show it
    char passwd_reversed[8] = { 0x0 };
    for (int k = 0; k < 7; k++)
    {
        int mod = k % 0x3f;
        passwd_reversed[k] = passwd[k] + decTable[mod];
    }

    printf("reversed password: %s\n\n", passwd_reversed);

    while (1)
    {
        printf("\n%dst input Passwd:", numOfTries);

        char inChar;
        int i = 0;
        char var_18[0x3f] = { 0x0 }; // encrypted user input

        char inStr[0x3f] = { 0x0 }; // original user input
        int inStrCounter = 0; // counter for current input character

        while (1)
        {
            inChar = getch();
            if (inChar == 0xD)
                break; // enter was pressed

            inStr[inStrCounter] = inChar;
            inStrCounter++;

            // Encrypt input char
            int mod = i % 0x3f;
            var_18[mod] = inChar - decTable[mod];
            i++;

            //var_18[mod - 0x40] = inChar - decTable[mod + 0x14];
            //var_18[mod - 0x3f] = 0;
        }

        // enter pressed, show input string and encrypted string
        printf("\nentered: %s  enc: %s\n", inStr, var_18);

        // verify password
        int cmp = strncmp(passwd, var_18, 7);
        if (cmp == 0)
        {
            printf("password OK\n");
            break;
        }
        else
            numOfTries++;
    }

    return 0;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.