Parse XML data and compare values

Viewed 31

I have an XML structure as below

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<answer>
    <flows>
        <flow>
            <reference type="from">
                <statement>
                    <statementfull>virtualinvoke $r0.&lt;de.foellix.sourceapp.SourceMainActivity: void startActivity(android.content.Intent)&gt;($r1)</statementfull>
                    <statementgeneric>de.foellix.sourceapp.SourceMainActivity: void startActivity(android.content.Intent)</statementgeneric>
                    <parameters>
                        <parameter>
                            <type>android.content.Intent</type>
                            <value>$r1</value>
                        </parameter>
                    </parameters>
                </statement>
                <method>&lt;de.foellix.sourceapp.SourceMainActivity: void source()&gt;</method>
                <classname>de.foellix.sourceapp.SourceMainActivity</classname>
                <app>
                    <file>C:/SIMApp.apk</file>
                    <hashes>
                        <hash type="MD5">e98d0f782a61c81ee8da971ebff5cec9</hash>
                        <hash type="SHA-1">e1516eff8cc99f9dfb49bea3a7ec8588e0c7a4ab</hash>
                        <hash type="SHA-256">492df0663a4ca21f22c7d9bb613b43d914a78352a4f77e548846f39b6e823c3</hash>
                    </hashes>
                </app>
            </reference>
            <reference type="to">
                <statement>
                    <statementfull>$r2 = virtualinvoke $r1.&lt;android.content.Intent: java.lang.String getStringExtra(java.lang.String)&gt;("Secret")</statementfull>
                    <statementgeneric>android.content.Intent: java.lang.String getStringExtra(java.lang.String)</statementgeneric>
                    <parameters>
                        <parameter>
                            <type>java.lang.String</type>
                            <value>"Secret"</value>
                        </parameter>
                    </parameters>
                </statement>
                <method>&lt;de.foellix.sinkapp.SinkMainActivity: void sink()&gt;</method>
                <classname>de.foellix.sinkapp.SinkMainActivity</classname>
                <app>
                    <file>C:/SMSApp.apk</file>
                    <hashes>
                        <hash type="MD5">505197d8859303afc60ffee8ff298f39</hash>
                        <hash type="SHA-1">9c2ef3ad3b0376f6c023bfca15f402f0eb00c976</hash>
                        <hash type="SHA-256">8a90c056a029f2d032705be20216e8888b735131304a128752e516ac21d87a03</hash>
                    </hashes>
                </app>
            </reference>
        </flow>
        <flow>
            <reference type="from">
                <statement>
                    <statementfull>virtualinvoke $r0.&lt;de.foellix.sourceapp.SourceMainActivity: void startActivity(android.content.Intent)&gt;($r1)</statementfull>
                    <statementgeneric>de.foellix.sourceapp.SourceMainActivity: void startActivity(android.content.Intent)</statementgeneric>
                    <parameters>
                        <parameter>
                            <type>android.content.Intent</type>
                            <value>$r1</value>
                        </parameter>
                    </parameters>
                </statement>
                <method>&lt;de.foellix.sourceapp.SourceMainActivity: void source()&gt;</method>
                <classname>de.foellix.sourceapp.SourceMainActivity</classname>
                <app>
                    <file>C:/SIMApp.apk</file>
                    <hashes>
                        <hash type="MD5">e98d0f782a61c81ee8da971ebff5cec9</hash>
                        <hash type="SHA-1">e1516eff8cc99f9dfb49bea3a7ec8588e0c7a4ab</hash>
                        <hash type="SHA-256">492df0663a4ca21f22c7d9bb613b43d914a78352a4f77e548846f39b6e823c3</hash>
                    </hashes>
                </app>
            </reference>
            <reference type="to">
                <statement>
                    <statementfull>virtualinvoke $r0.&lt;de.foellix.sourceapp.SourceMainActivity: void startActivity(android.content.Intent)&gt;($r1)</statementfull>
                    <statementgeneric>de.foellix.sourceapp.SourceMainActivity: void startActivity(android.content.Intent)</statementgeneric>
                    <parameters>
                        <parameter>
                            <type>android.content.Intent</type>
                            <value>$r1</value>
                        </parameter>
                    </parameters>
                </statement>
                <method>&lt;de.foellix.sourceapp.SourceMainActivity: void source()&gt;</method>
                <classname>de.foellix.sourceapp.SourceMainActivity</classname>
                <app>
                    <file>C:/SIMApp.apk</file>
                    <hashes>
                        <hash type="MD5">e98d0f782a61c81ee8da971ebff5cec9</hash>
                        <hash type="SHA-1">e1516eff8cc99f9dfb49bea3a7ec8588e0c7a4ab</hash>
                        <hash type="SHA-256">492df0663a4ca21f22c7d9bb613b43d914a78352a4f77e548846f39b6e823c3</hash>
                    </hashes>
                </app>
            </reference>
        </flow>
      ...
    </flows>
</answer>

I am looking to parse this XML data where there are multiple <flow> elements within the element.

For each <flow> element I want to compare the <hash type="SHA-256"> values inside the <reference type="from"> and <reference type="to"> and get only the <flow> elements in which the <hash type="SHA-256"> values are different.

For example for the above XML the output should look something like this

<flow>
    <reference type="from">
        <statement>
            <statementfull>virtualinvoke $r0.&lt;de.foellix.sourceapp.SourceMainActivity: void startActivity(android.content.Intent)&gt;($r1)</statementfull>
            <statementgeneric>de.foellix.sourceapp.SourceMainActivity: void startActivity(android.content.Intent)</statementgeneric>
            <parameters>
                <parameter>
                    <type>android.content.Intent</type>
                    <value>$r1</value>
                </parameter>
            </parameters>
        </statement>
        <method>&lt;de.foellix.sourceapp.SourceMainActivity: void source()&gt;</method>
        <classname>de.foellix.sourceapp.SourceMainActivity</classname>
        <app>
            <file>C:/SIMApp.apk</file>
            <hashes>
                <hash type="MD5">e98d0f782a61c81ee8da971ebff5cec9</hash>
                <hash type="SHA-1">e1516eff8cc99f9dfb49bea3a7ec8588e0c7a4ab</hash>
                <hash type="SHA-256">492df0663a4ca21f22c7d9bb613b43d914a78352a4f77e548846f39b6e823c3</hash>
            </hashes>
        </app>
    </reference>
    <reference type="to">
        <statement>
            <statementfull>$r2 = virtualinvoke $r1.&lt;android.content.Intent: java.lang.String getStringExtra(java.lang.String)&gt;("Secret")</statementfull>
            <statementgeneric>android.content.Intent: java.lang.String getStringExtra(java.lang.String)</statementgeneric>
            <parameters>
                <parameter>
                    <type>java.lang.String</type>
                    <value>"Secret"</value>
                </parameter>
            </parameters>
        </statement>
        <method>&lt;de.foellix.sinkapp.SinkMainActivity: void sink()&gt;</method>
        <classname>de.foellix.sinkapp.SinkMainActivity</classname>
        <app>
            <file>C:/SMSApp.apk</file>
            <hashes>
                <hash type="MD5">505197d8859303afc60ffee8ff298f39</hash>
                <hash type="SHA-1">9c2ef3ad3b0376f6c023bfca15f402f0eb00c976</hash>
                <hash type="SHA-256">8a90c056a029f2d032705be20216e8888b735131304a128752e516ac21d87a03</hash>
            </hashes>
        </app>
    </reference>
</flow>

I am new to using the xml.etree.ElementTree in Python. Could anyone guide me in the right direction?

1 Answers

If I understand it correctly, you want to select flow elements whose "from" hash is different to their "to" hash?

You could use retrieve these flow elements using the ElementTree's findall method, with the following XPath expression

//flow[
   reference[@type='from']/app/hashes/hash[@type='SHA-256'] != 
   reference[@type='to']/app/hashes/hash[@type='SHA-256']
]
Related