Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to decode the string length when it is very long? #1587

Closed
cmeiyuan opened this issue Aug 14, 2017 · 7 comments
Closed

How to decode the string length when it is very long? #1587

cmeiyuan opened this issue Aug 14, 2017 · 7 comments
Labels

Comments

@cmeiyuan
Copy link

As we know,we use StringBlock.getUtf8() or StringBlock.getUtf16() to decode the string's length,usually they can work well.
but,when a string is very very long,such as the length is 0x8888,so the first four bytes are [0x88,0x88,0x88,0x88].

How should I decode it's length?

image

@iBotPeaches
Copy link
Owner

Do you have an APK with these large string block entry? I will investigate.

@cmeiyuan
Copy link
Author

I'm sorry to have given you so late.

app-debug.apk.zip

@iBotPeaches
Copy link
Owner

Apktool seems to be decoding this fine. So unsure what you are asking. If you are asking how it does it.

Read this: https://github.com/iBotPeaches/platform_frameworks_base/blob/apktool_7.1/include/androidfw/ResourceTypes.h#L420

/**
 * Definition for a pool of strings.  The data of this chunk is an
 * array of uint32_t providing indices into the pool, relative to
 * stringsStart.  At stringsStart are all of the UTF-16 strings
 * concatenated together; each starts with a uint16_t of the string's
 * length and each ends with a 0x0000 terminator.  If a string is >
 * 32767 characters, the high bit of the length is set meaning to take
 * those 15 bits as a high word and it will be followed by another
 * uint16_t containing the low word.
 *
 * If styleCount is not zero, then immediately following the array of
 * uint32_t indices into the string table is another array of indices
 * into a style table starting at stylesStart.  Each entry in the
 * style table is an array of ResStringPool_span structures.
 */

@cmeiyuan
Copy link
Author

cmeiyuan commented Aug 16, 2017

I think StringBlock has a bug than can not decode length correctly.

app-debug.zip

1. I define a very long string in strings.xml.

image

2. I toast the string's length in MainActivity.java, the length is 0x8888.

public class MainActivity extends AppCompatActivity {

    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.tv_hello);
        String str = getString(R.string.test);
        // the length of str is 0x8888
        Toast.makeText(this, "0x" + Integer.toHexString(str.length()), Toast.LENGTH_SHORT).show();
        textView.setText(str);
    }
}

3. I decode the length by ARSCDecoder.java, but the length is 0x888.

I modify the ARSCDecoder.java that only change some private fields to public and I will upload it.

public static void main(String[] args) throws Exception {
    // I unzip app-debug.apk to get the file resources.arsc
    File file = new File("/Users/cmeiyuan/AndroidStudioProjects/RePlugin/replugin-sample/MyApplication4/app/build/outputs/apk/app-debug/resources.arsc");
    FileInputStream in = new FileInputStream(file);
    try {
        ARSCDecoder decoder = new ARSCDecoder(in, new ResTable(), true, true);
        decoder.readTableHeader();
        StringBlock stringBlock = decoder.mTableStrings;
        int count = stringBlock.getCount();
        for (int i = 0; i < count; i++) {
            String s = stringBlock.get(i).toString();
            if (s.startsWith("aaaaa")) {
                // console print:
                // aaaaaaaaaa.....
                // length:2184
                System.out.println(s);
                System.out.println("length:" + s.length());
            }
        }
    } catch (IOException ex) {
        throw new AndrolibException("Could not decode arsc file", ex);
    }
}

@iBotPeaches
Copy link
Owner

Thanks for the detailed explanation. I will take another look.

@cmeiyuan
Copy link
Author

Ok!Thanks very much!

@iBotPeaches
Copy link
Owner

iBotPeaches commented Aug 16, 2017

Interesting find. I have tests for this - https://github.com/iBotPeaches/Apktool/blob/master/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/res/values-en/strings.xml

But it seems in the case of a 0x8888 character string it fails. This is similar to #1291. I guess the UTF16 decoding is improperly determining the length.

Confirmed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants