<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" 
  xmlns:content="http://purl.org/rss/1.0/modules/content/" 
  xmlns:dc="http://purl.org/dc/elements/1.1/" 
  xmlns:atom="http://www.w3.org/2005/Atom" 
  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" 
  xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>cortex-m on Ben&#39;s ideas and projects</title>
    <link>https://ben.the-collective.net/tags/cortex-m/</link>
    <description>Recent content in cortex-m on Ben&#39;s ideas and projects</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <managingEditor>locutus@the-collective.net (Ben Mason)</managingEditor>
    <webMaster>locutus@the-collective.net (Ben Mason)</webMaster>
    <copyright>©2023, All Rights Reserved</copyright>
    <lastBuildDate>Tue, 15 Feb 2022 09:00:00 -0500</lastBuildDate>
    <sy:updatePeriod>daily</sy:updatePeriod>
    
        <atom:link href="https://ben.the-collective.net/tags/cortex-m/index.xml" rel="self" type="application/rss+xml" />
    

      
      <item>
        <title>Reversing ARM Cortex-M Bit Band addresses</title>
        <link>https://ben.the-collective.net/posts/2022-02-15-reversing-arm-cortex-m-bit-band-addresses/</link>
        <pubDate>Tue, 15 Feb 2022 09:00:00 -0500</pubDate>
        <author>locutus@the-collective.net (Ben Mason)</author>
        <atom:modified>Tue, 15 Feb 2022 09:00:00 -0500</atom:modified>
        <guid>https://ben.the-collective.net/posts/2022-02-15-reversing-arm-cortex-m-bit-band-addresses/</guid>
        <description>While reverse-engineering the firmware on the Digoo DG-HOSA device which I have a couple of posts on already. I ran across some memory addresses that did not directly map to peripherals. I found the address ranges are called the Bit-band range and had special functionality allowing direct access to individual bits on peripherals. This post will give a quick summary of what these addresses are and how to unmap them to the normal peripheral addresses.</description>
        <content:encoded>&lt;p&gt;While reverse-engineering the firmware on the &lt;a href=&#34;https://ben.the-collective.net/tag/digoo-dg-hosa/&#34;&gt;Digoo DG-HOSA device which I have a couple of posts on already&lt;/a&gt;. I ran across some memory addresses that did not directly map to peripherals. I found the address ranges are called the Bit-band range and had special functionality allowing direct access to individual bits on peripherals. This post will give a quick summary of what these addresses are and how to unmap them to the normal peripheral addresses.&lt;/p&gt;
&lt;h2 id=&#34;what-is-bit-banding&#34;&gt;What is Bit Banding?&lt;/h2&gt;
&lt;p&gt;The Bit Banding is a feature of the ARM Cortex-M3/M4 allowing you to directly access specific bits within the Peripheral and SRAM regions. Normally you need to write a whole register at a time even if you want to change a single bit. There are memory regions allocated for this purpose they are named “Bit band alias” in this snip of the Processor memory map table.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../reversing-arm-cortex-m-bit-band-addresses-images/Screen-Shot-2022-01-28-at-15.46.58.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;
&lt;p&gt;From &lt;a href=&#34;https://www.keil.com/dd/docs/datashts/arm/cortex_m3/r2p0/ddi0337g_cortex_m3_r2p0_trm.pdf&#34;&gt;Cortex-M3 Technical Reference&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To calculate the Bit band address for a specific bit on a port you use the following formula. This formula is also found in the &lt;a href=&#34;https://www.keil.com/dd/docs/datashts/arm/cortex_m3/r2p0/ddi0337g_cortex_m3_r2p0_trm.pdf&#34;&gt;Cortex-M3 Technical reference&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;bit_word_addr = bit_band_base + ((byte_offset x 32) + (bit_number × 4))&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;bit_word_offset&lt;/strong&gt; – position of the target bit in the bit-band memory region.&lt;br /&gt;
&lt;strong&gt;bit_word_addr&lt;/strong&gt; – address of the word in the alias memory region that maps to the targeted bit.&lt;br /&gt;
&lt;strong&gt;bit_band_base&lt;/strong&gt; – starting address of the alias region.&lt;br /&gt;
&lt;strong&gt;byte_offset&lt;/strong&gt; – number of the byte in the bit-band region that contains the targeted bit.&lt;br /&gt;
&lt;strong&gt;bit_number&lt;/strong&gt; – bit position (0-7) of the targeted bit.&lt;/p&gt;
&lt;p&gt;This was a quick introduction to bit banding if you are looking for more information check out his post which goes into great detail on this feature.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://atadiat.com/en/e-bit-banding-explained-a-feature-of-arm-cortex-m3/&#34;&gt;Bit-banding Explained: A Key Feature of ARM Cortex-M3/M4&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;now-to-reverse-a-bit-mapped-address&#34;&gt;Now to reverse a bit mapped address&lt;/h2&gt;
&lt;p&gt;Now that we how to forward map an address I wrote up some python code that takes in the address, unmaps it, and lists the original port and register information.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/usr/bin/python

def find_base_addr(bitmapped):
    if (0x22000000 &amp;lt; bitmapped and bitmapped &amp;lt; 0x23FFFFFF):
        bit_band_base = 0x22000000
        base_address = 0x20000000
    elif (0x42000000 &amp;lt; bitmapped and bitmapped &amp;lt; 0x43FFFFFF):
        bit_band_base = 0x42000000
        base_address = 0x40000000
    else:
        bit_band_base = 0
        base_address = 0
    return bit_band_base, base_address

def bitunmapper(bitmapped):
    bit_band_base, base_address = find_base_addr(bitmapped)
    unmap_port = int(((bitmapped - bit_band_base) &amp;amp; 0xfffff00) / 32)
    unmap_bits = int((bitmapped &amp;amp; 0x000000FF) / 4)
    if unmap_bits &amp;gt; 32:
        unmap_port += 0x4
        unmap_bits %= 32
    unmapped_address = base_address + int(unmap_port)
    
    print(&amp;#34;Base Address: &amp;#34; + hex(unmapped_address))
    print(&amp;#34;Port: &amp;#34; + hex(unmapped_address &amp;amp; 0xFFFFFF00))
    print(&amp;#34;Register: &amp;#34; + hex(unmapped_address &amp;amp; 0x000000FF))
    print(&amp;#34;Bit Map: &amp;#34; + str(int(unmap_bits)))

bitunmapper(0x4221811c)
bitunmapper(0x42218188) # GPIOB 2
bitunmapper(0x42218198) # GPIOB 6
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I have also created a Ghidra plugin using this code to quickly resolve these addresses when working through a binary. You can download it from this link:&lt;br /&gt;
&lt;a href=&#34;https://github.com/suidroot/ghidra_scripts/blob/main/arm-bit-unmapper.py&#34;&gt;https://github.com/suidroot/ghidra_scripts/blob/main/arm-bit-unmapper.py&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Finally, here is a couple of screenshots of the plugin in action.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../reversing-arm-cortex-m-bit-band-addresses-images/Screen-Shot-2022-02-13-at-15.02.19.png&#34; alt=&#34;Enter Address&#34; /&gt;&lt;br /&gt;
&lt;img src=&#34;../reversing-arm-cortex-m-bit-band-addresses-images/Screen-Shot-2022-02-13-at-15.02.53.png&#34; alt=&#34;Results in the console&#34; /&gt;&lt;/p&gt;
</content:encoded>
        <dc:creator>suidroot</dc:creator>
        <media:content url="https://ben.the-collective.net/images/post-images/Reversing-ARM-Cortex-M-Bit-Band-addresses.png" medium="image"><media:title type="html">featured image</media:title></media:content>
        
        
        
          
            
              <category>arm</category>
            
          
            
              <category>cortex-m</category>
            
          
            
              <category>ghidra</category>
            
          
            
              <category>python</category>
            
          
            
              <category>reverse engineering</category>
            
          
        
        
          
            
              <category>Reverse Engineering</category>
            
          
            
              <category>Electronics</category>
            
          
        
        
      </item>
      

    
  </channel>
</rss>
